How to properly use Optional to cleanse your Java code of NullPointerExceptions

Since the creation of null in the 1960s by Tony Hoare, null or some form of it whether it be nilor None, has crept its way into many languages today as a convenient way to signify a non-existent object. In doing so, it has caused problems from making developers pull their hair out trying to track down a null reference, to even taking systems in production down.

What’s the problem with null?

Take for example the following snippet:

  • homeListing could now be null if the id isn’t in the database resulting in homeListing.getPrice() throwing another NullPointerException.
  • homeListing could also not have a price yet, in which case listingPrice is now null which results in listingPrice > EXPENSIVE_HOME_THRESHOLD to throw a NullPointerException.

Save me! What is Optional and how can we use it?

From the Oracle Java docs:

How does this help us?

To see how these operations can be useful in the context of Optional, let’s take a look at their implementations. Let’s look at map first:

public Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return Optional.empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent()) {
return Optional.empty();
} else {
return predicate.test(value) ? this : empty();
}
}

Psh this seems like a contrived example. Show me more code!

The snippet below demonstrates retrieving a list of HomePhotos from a given propertyId. In this example, there can be multiple HomeListing s per property and it will choose the first one to get the photos.

Is this really doing the same thing as the original snippet?

You bet! First, the propertyId is ensured to not be null. Then, propertyRoDAO::getHomeListings fetches the List<HomeListing> and is converted to a Stream<HomeListing>. The findFirst method is called on the Stream.

All of this sounds great… but can’t Optional be null too?

Unfortunately because Optional is not actually a primitive, it has the ability to be null as well effectively defeating all of the advantages of using Optional in the first place. It’s ultimately up to the developers and perhaps even static analysis tools to ensure that null doesn’t get returned from a method that has a return type of Optional. Even though there might be no guarantee on whether a given method that returnsOptional will be null or not, it’s still safe to construct an Optional locally to take advantage of map , filter , and flatMap to reduce the amount of manual null checking that has be done.

Optional is great, but how do I deal with null in other languages?

Today, programming languages vary in their ways of dealing with the billion dollar mistake.

if (obj != null) {
if (obj.getObjTwo() != null) {
obj.getObjTwo().doSomething();
}
}

Closing Thoughts

null has become a staple in many languages, and it’s not going away anytime soon. Despite the fact that null still causes major issues in production systems today, it’s reassuring to see that developers are actively trying to find ways to introduce features to better mitigate the holes that these type systems have.

CS @ UW • SDE @ Amazon • http://www.justinharjanto.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store