Avoiding the Null Pointer Exception With Optional in Java
Tags: java, programming
Published: 2020-12-08 14:03:58

---
title: Avoiding the Null Pointer Exception With Optional in Java
published: true
tags: Java,Programming
canonical_url: https://codecurated.com/blog/avoiding-the-null-pointer-exception-with-optional-in-java/
---

 ![Avoiding the Null Pointer Exception With Optional in Java](https://codecurated.com/content/images/2020/11/barnabas-hertelendy-nT5ZPS9TgPQ-unsplash-1.jpg)

In 1964, British computer scientist Tony Hoare invented the Null Pointer References.

The Null Pointer Exception has contributed the most bugs in production exceptions. It was implemented in many programming languages, including C, C++, C#, JavaScript, Java, and more.

The loss of financial resources, time, and human resources to fix it prompted Hoare to call it a “[billion-dollar mistake](https://qconlondon.com/london-2009/qconlondon.com/london-2009/speaker/Tony+Hoare.html).”

Java is one of the programming languages that implement Null Pointer References. If you’ve been developing with Java, I’m sure that you’ve seen them a lot. It doesn’t matter if you are new to Java or have ten years of experience. There is always a chance that you’ll encounter a Null Pointer Exception bug.

* * *

## Optional in Java

`Optional` is an API that was introduced in Java 8. If used right, it can solve the problem of the Null Pointer Exception.

Optional API implements functional programming and uses Functional Interface.

If you want to know more about Functional Programming in Java you can read my other article, [Functional Programming in Java, Explained](https://codecurated.com/blog/functional-programming-in-java-explained/).

Before we proceed any further, please note that I’m using Java 11 for the examples in this article. If you’re using a different version of Java, some methods might not exist or behave exactly the same.

* * *

## Empty Optional

An empty `optional` is the main way to avoid the Null Pointer Exception when using the `Optional` API.

In `Optional`’s flow, a null will be transformed into an empty `Optional`. The empty `Optional` won’t be processed any further. This is how we can avoid a `NullPointerException` when using `Optional`.

We will learn further about how an empty `Optional` behaves later in this article.

* * *

## Creating Optional object

There are three ways to initiate an `Optional` object:

- `Optional.of(T)`
- `Optional.ofNullable(T)`
- `Optional.empty()`

### Optional.of

`Optional.of` accepts any type with a non-nullable value in its parameter. To create an `Optional` object with `Optional.of`, we just have to pass a value in its parameter.

```
    @Test
    public void initializeOptional_optionalOf() {
        Optional<String> helloWorldOptional = Optional.of("Hello, world");
        assert helloWorldOptional.isPresent();
        assert "Hello, world".equals(helloWorldOptional.get());
    }
```

Be very careful when you are passing a value to the `Optional.of`. Remember that `Optional.of` doesn’t accept null values in its parameter. If you try to pass a null value, it will produce a `NullPointerException`.

```
     @Test
    public void initializeOptional_optionalOf_null() {
        try {
            Optional.of(null);
        } catch (Exception e) {
            assert e instanceof NullPointerException;
        }
    }
```

### Optional.ofNullable

`Optional.ofNullable` is similar to Optional.of. It accepts any type. The difference is, with `Optional.ofNullable`, you can pass a null value to its parameter.

```
    @Test
    public void initializeOptional_optionalOfNullable() {
        Optional<String> helloWorldOptional = Optional.ofNullable("Hello, world");
        assert helloWorldOptional.isPresent();
        assert "Hello, world".equals(helloWorldOptional.get());
    }
```

When `Optional.ofNullable` is initialized using a null object, it will return an empty `Optional`.

```
    @Test
    public void initializeOptional_optionalOfNullable_null() {
        Optional<String> helloWorldOptional = Optional.ofNullable(null);
        assert !helloWorldOptional.isPresent();
        try {
            helloWorldOptional.get();
        } catch (Exception e) {
            assert e instanceof NoSuchElementException;
        }
    }
```

### Optional.empty

An empty `Optional` can be initialized by using `Optional.empty()`.

```
    @Test
    public void initializeOptional_optionalEmpty() {
        Optional<String> helloWorldOptional = Optional.empty();
        assert !helloWorldOptional.isPresent();
    }
```

## Accessing Optional

There are some ways to get the value of an Optional.

### get

A pretty straightforward method. The `get` method will return the value of `Optional` if it is present and throw a `NoSuchElementException` if the value doesn’t exist.

```
    @Test
    public void get_test() {
        Optional<String> helloWorldOptional = Optional.of("Hello, World");
        assert "Hello, World".equals(helloWorldOptional.get());
    }

    @Test
    public void get_null_test() {
        Optional<String> helloWorldOptional = Optional.empty();
        try {
            helloWorldOptional.get();
        } catch (Exception e) {
            assert e instanceof NoSuchElementException;
        }
    }
```

### orElse

If you want to use a default value if the `Optional` is empty, you can use the `orElse` method.

```
    @Test
    public void orElse_test() {
        Optional<String> helloWorldOptional = Optional.of("Hello, World");
        assert "Hello, World".equals(helloWorldOptional.orElse("default"));
    }

    @Test
    public void orELseNull_test() {
        Optional<String> helloWorldOptional = Optional.empty();
        assert "default".equals(helloWorldOptional.orElse("default"));
    }
```

### orElseGet

`orElseGet` is very similar to the `orElse` method. It’s just that `orElseGet` accepts `Supplier<T>` as its parameter.

```
    @Test
    public void orElseGet_test() {
        Optional<String> helloWorldOptional = Optional.of("Hello, World");
        assert "Hello, World".equals(helloWorldOptional.orElseGet(() ->"default"));
    }

    @Test
    public void orELseGet_Null_test() {
        Optional<String> helloWorldOptional = Optional.empty();
        assert "default".equals(helloWorldOptional.orElseGet(() ->"default"));
    }
```

### orElseThrow

`orElseThrow` will return the value of the `Optional` or throw an exception if the value of the `Optional` is empty.

```
    @Test
    public void orElseThrow_test() {
        Optional<String> helloWorldOptional = Optional.of("Hello, World");
        assert "Hello, World".equals(helloWorldOptional.orElseThrow(NullPointerException::new));
    }

    @Test
    public void orELseThrow_Null_test() {
        Optional<String> helloWorldOptional = Optional.empty();
        try {
            helloWorldOptional.orElseThrow(NullPointerException::new);
        } catch (Exception e) {
            assert e instanceof NullPointerException;
        }
    }
```

## Processing an Optional

There are many ways to process and transform an `Optional`. In this section, we will learn the common methods that are used.

As I wrote at the beginning of the article, an empty `Optional` won’t be processed in the flow. We can see that from the examples in this section.

### Map

`map` is the most used method when processing an `Optional` object. It accepts `Function<? super T, ? extends U>` as its parameter and returns an `Optional<U>.` This means you can use a Function with any type of parameter and the return value will be wrapped to `Optional` in the `map` method.

```
    @Test
    public void processingOptional_map_test() {
        Optional<String> stringOptional = Optional.of("Hello, World")
                .map(a -> a + ", Hello");

        assert stringOptional.isPresent();
        assert "Hello, World, Hello".equals(stringOptional.get());
    }
```

If you try to return a null value in `Function<? super T, ? extends U>`, the `map` method will return an empty `Optional`.

```
    @Test
    public void processingOptional_map_empty_test() {
        Optional<String> stringOptional = Optional.of("Hello, World")
                .map(a -> null);

        assert !stringOptional.isPresent();
    }
```

An empty optional won’t be processed by `map`. We can confirm this with the following test:

```
    @Test
    public void processingOptional_map_empty_notProcessed_test() {
        AtomicBoolean atomicBoolean = new AtomicBoolean(false);
        Optional<String> stringOptional = Optional.of("Hello, World")
                .map(a -> null)
                .map(a -> {
                    atomicBoolean.set(true);
                    return "won't be processed";
                });

        assert !stringOptional.isPresent();
        assert atomicBoolean.get() == false;
    }
```

### FlatMap 

This is similar to `map`, but `flatMap` won’t wrap the return value of the Function to `Optional`. The `flatMap` method accepts `Function<? super T, ? extends Optional<? extends U>>` as its parameter. This means that you’ll need to define a Function that accepts any type and returns an `Optional`.

You will usually use the `flatMap` method when your code calls another method that returns an `Optional` object.

```

    @Test
    public void processingOptional_flatmap_test() {
        Optional<String> stringOptional = Optional.of("Hello, World")
                .flatMap(this::getString);

        assert "Hello, World, Hello".equals(stringOptional.get());
    }

    @Test
    public void processingOptional_flatmap_randomString_test() {
        Optional<String> stringOptional = Optional.of(UUID.randomUUID().toString())
                .flatMap(this::getString);

        assert !stringOptional.isPresent();
    }

    public Optional<String> getString(String s) {
        if ("Hello, World".equals(s)) {
            return Optional.of("Hello, World, Hello");
        }
        return Optional.empty();
    }
```

### Filter

In the previous example of `flatMap`, we used a declarative style to differentiate the return value of the `getString` method. But we can actually use a functional style for that with the `filter` method.

```
   @Test
    public void processingOptional_filter_test() {
        Optional<String> stringOptional = Optional.of("Hello, World")
                .filter(helloWorldString -> "Hello, World".equals(helloWorldString))
                .map(helloWorldString -> helloWorldString + ", Hello");

        assert "Hello, World, Hello".equals(stringOptional.get());
    }

    @Test
    public void processingOptional_filter_randomString_test() {
        Optional<String> stringOptional = Optional.of(UUID.randomUUID().toString())
                .filter(helloWorldString -> "Hello, World".equals(helloWorldString))
                .map(helloWorldString -> helloWorldString + ", Hello");

        assert !stringOptional.isPresent();
    }
view rawProcessingOptionalT
```

### If Present

The `ifPresent` method accepts a `Consumer` that will only be executed if the Optional is not empty.

```
    @Test
    public void processingOptional_ifPresent_test() {
        AtomicBoolean atomicBoolean = new AtomicBoolean(false);
        Optional.of("Hello, World")
            .ifPresent(helloWorldString -> atomicBoolean.set(true));
        assert atomicBoolean.get();
    }

    @Test
    public void processingOptional_ifPresent_empty_test() {
        AtomicBoolean atomicBoolean = new AtomicBoolean(false);
        Optional.empty()
                .ifPresent(helloWorldString -> atomicBoolean.set(true));
        assert !atomicBoolean.get();
    }
```

## Things to avoid

There are some critical things that you need to avoid if you want to use `Optional` in your code.

### Don’t create a method that accepts Optional

Creating a method that accepts `Optional` as a parameter might introduce a problem it wants to solve, `NullPointerException`.

If a person using the method with the `Optional` parameter is not aware of it, they might pass a null to the method instead of `Optional.empty()`. Processing a `null` will produce a `NullPointerException`.

```
    @Test
    public void optionalAsParameter_test() {
        try {
            isPhoneNumberPresent(null);
        } catch (Exception e) {
            assert e instanceof NullPointerException;
        }
    }

    public boolean isPhoneNumberPresent(Optional<String> phoneNumber) {
        return phoneNumber.isPresent();
    }
```

### Getting value without checking

If you’re using `Optional`, then you should avoid using the get method if you can. If you still want to use it for some reason, make sure that you check it with the `isPresent` method first because if you use get on an empty `Optional`, it will produce a `NoSuchMethodException`.

```
    @Test
    public void getWithIsPresent_test() {
        Optional<String> helloWorldOptional = Optional.ofNullable(null);
        if (helloWorldOptional.isPresent()) {
            System.out.println(helloWorldOptional.get());
        }
    }

    @Test
    public void getWithoutIsPresent_error_test() {
        Optional<String> helloWorldOptional = Optional.ofNullable(null);
        try {
            System.out.println(helloWorldOptional.get());
        } catch (Exception e) {
            assert e instanceof NoSuchElementException;
        }
    }
```

## Conclusion

Thank you for reading until the end! Optional is a powerful feature that every Java developer should know about. If you use optional features from end to end correctly, then I’m sure that you won’t meet the `NullPointerException` anymore.

Optional is also used as a base for other big libraries like Reactor and RXJava, so knowing how Optional works will help you understand them too.

You can find the repository with the examples in this article below:

[https://github.com/brilianfird/java-optional](https://github.com/brilianfird/java-optional)

References

1. [Null Pointer References: The Billion Dollar Mistake](https://codecurated.com/p/5ab1a3fc-adaf-415e-a4f5-1f6c6f4c2bdb/References%20Null%20Pointer%20References:%20The%20Billion%20Dollar%20Mistake%20https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions%20https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)
2. [https://en.wikipedia.org/wiki/Tony\_Hoare#Apologies\_and\_retractions](https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions)
3. [https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)