Thomas Skardal

Hello, computer.

Optional, what is it good for?

February 21, 2015

NullPointerExceptions. They occur everywhere and are often caused by stupid programming mistakes. Its a really common problem in Java applications. And the guy that first introduced null references calls it the billion dollar mistake.

Many programming languages have a solution to this. In idiomatic Scala you don’t use null. You would use Option instead with either Some value or None. Haskell has the Maybe monad. Clojure has no optional type, but most functions deal with nil and empty lists in a way that makes it close to transparent. This blog post gives some good examples. See the sixth point.

This can (and should) be done in Java too! In Java 8 Optional was added, and earlier versions could get an implementation from libraries like Guava. Using optional make it explicit where a value may or may not be present. You don’t have to read code or documentation in order to figure out if you have to do a null check. Maybe you just add a null check to feel safe. I’m sure you’ve seen code bases bloated with null checks.

Optionals aren’t just about using isPresent() instead of != null in if statements. This slideshow presents some good arguments for why it is a good practice, and what benefits it gives.

Here’s some sample code copied from the slides:

String getCarInsuranceName(Person person) {
  if (person != null) {
    Car car = person.getCar();
    if (car != null) {
      Insurance insurance = car.getInsurance();
      if(insurance != null) {
        return insurance.getName();
      }
    }
  }
  return "Unknown";
}

This is a rather small sample, but still, a lot of null checks! I’m sure most of us have seen worse. Let’s have a look at how this could have been if using optionals (also copied from the slides).

String getCarInsuranceName(Optional<Person> person) {
  return person.flatMap(person -> person.getCar())
               .flatMap(car -> car.getInsurance())
               .map(insurance -> insurance.getName())
               .orElse("Unknown");
}

This looks much better! And in my opinion this should be the preferred way of doing it. I’m sure it can be exploited and misused, but mostly, you would benefit from it.