Java beans With the introduction of Java 8 we also got a new class to our disposal: java.util.Optional. The correct usage of this class, especially together with streams, can result in much cleaner code. But not always does it have benefits.

Optional instead of if-else

Many times I see constructs like this:

Optional.ofNullable(a).ifPresent(x -> doSomething(x))

Instead of the ‘old style’ if statement:

if (i != null) {
  doSomething(i);
}

I still think the if-statement is much more readable. In this wrapping it in an Optional doesn’t give us any benefit. Even more so: the performance of Optional in this case is much worse than using a simple if-statement, because of instantiating an additional object and having additional method class. In this case I would just go for the if-statement.

Sometimes the usage of Optional supposedly would give better readability than an if-statement:

return Optional.ofNullable(a)
  .map(Foo::new)
  .orElseThrow(IllegalArgumentException::new)

Instead of:

if (a != null) {
  return new Foo(a);
} else {
  return new IllegalArgumentException();
}

But for static code analysis tools like SonarQube it becomes much harder to determine which code paths there are and which one you tested. So that’s also something to consider.

Optional when designing APIs

The case where Optional can really help out is when designing APIs.

Currently I follow these rules:

  • If a method can return an empty value (i.e. null), then declare the return type al Optional and return Optional.empty().
  • If a method does not declare Optional as its return type, then I as a caller of the method may assume that the return value is never null.
  • Parameters are never of type Optional and so they are never null. This communicates the intent and possible cases much better to the user of the API and forces the caller to handle specific cases. Parameters that can be null are actually additional code paths in a method that can better be solved in a different way: using polymorphism or overloaded methods.

Disadvantages of Optional

It makes debugging a little bit harder because it wraps the actual value it represents.

Optional is not Serializable which makes it difficult to use it as a type of a field.

Conclusion

Everything considered I must conclude that: only use Optional as return type of methods when designing APIs and in other cases just use if-else-statements. This clearly communicates the intent, but also keeps code readable and simple.

And simple is always better.