1. Overview

In Java, a reference may or may not point to an object in memory. In other words, a reference can be null. As a result, this gives rise to the possibility of a NullPointerException being thrown.

To address this, the Optional class was introduced in Java 8. Wrapping a reference in an Optional allows us to better express the possibility of a value being present or not. Further, we can make use of the various utility methods on the Optional class such as isPresent() to avoid running into a NullPointerException.

We can use the the static factory methods Optional.of() and Optional.ofNullable() methods to obtain an Optional for a given reference. However, which one should we use? In this tutorial, we’ll explore the differences between these methods and understand when yo use which*.* 

2. The Optional.of() Method

We should use the Optional.of() static factory method when we’re sure that we have a non-null reference.

Let’s suppose we have a local String variable from which we want to obtain an Optional:

@Test
void givenNonNullReference_whenUsingOptionalOf_thenObtainOptional() {
    String s = "no null here";
    assertThat(Optional.of(s))
      .isNotEmpty()
      .hasValue("no null here");
}

From our assertion, we can see that our optional isn’t empty. In other words, the utility method isPresent(), which returns whether an Optional has a value or not, would return true. 

However, we’ll encounter a NullPointerException when we use this method on a null reference.

@Test
void givenNullReference_whenUsingOptionalOf_thenNullPointerExceptionThrown() {
    String s = null;
    assertThatThrownBy(() -> Optional.of(s))
      .isInstanceOf(NullPointerException.class);
}

3. The Optional.ofNullable() Method

We should use the Optional.ofNullable() static factory method when we have a reference that may or may not be null. Thus, we won’t encounter a NullPointerException for a reference that’s null. Instead, we’ll obtain an empty Optional:

@Test
void givenNullReference_whenUsingOptionalOfNullable_thenObtainOptional() {
    String s = null;
    assertThat(Optional.ofNullable(s)).isEmpty();
}

It’s fair to ask why we shouldn’t always use Optional.ofNullable() over Optional.of().

Using Optional.of() allows us to stop the execution of our code immediately by throwing an exception. This occurs, as we’ve previously discovered when obtaining an Optional for a reference that is null. In other words, the use of the Optional.of() method allows us to adhere to the principle of fail-early.

On a side note, we may encounter developers using these static factory methods as an entry point to make use of functional programming. This is achieved by using the methods on the Optional class that use function objects as method arguments such as map().

4. Conclusion

In this article, we learned the main differences between the static factory methods Optional.of() and Optional.ofNullable() and when it’s most appropriate to use them.

We saw how we can utilize the Optional class to help avoid throwing NullPointerException‘s.

Finally, we touched on the principle of fail-early and how adhering to this principle can influence which static factory method to use.

As always, the code samples used in this article are available over on GitHub.