This is a follow up to a previous article I wrote, Java’s new Optional type is worthless. If you want to skip my ranting and get straight to the practical stuff, scroll down to “How to use Optional the way it was intended.”

There was a lot of discussion on reddit and hacker news regarding my last article, which was both surprising and cool. As you’d expect, there was disagreement with some of the points I made. At the core of this disagreement is the idea that Optional is not meant to solve the problems many think it should, and actually serves a very specific purpose. As it turns out, this is true.

A Stack Overflow answer by Brian Goetz, Java’s language architect, sheds light on Oracle’s intention with the Optional type:

Of course, people will do what they want. But we did have a clear intention when adding this feature, and it was not to be a general purpose Maybe or Some type, as much as many people would have liked us to do so. Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent “no result”, and using null for such was overwhelmingly likely to cause errors.

There are a couple of things about this quote that bother me. First — If Optional is not a general purpose Option type, then don’t give it a name and high level description that would imply it is.

Second — If there’s a clear intention for Optional, DOCUMENT IT. Fewer people will “do what they want” if they have documentation that tells them not to. Instead, authoritative information about a type that lives in the java.util namespace exists as a Stack Overflow answer.

Anyway, that’s the end of my rant. Onto more practical things…

How to use Optional the way it was intended

Use Optional only as a return type for methods, and never, under any circumstances, return null.

Where possible, use the `orElse()` method to access the wrapped value. This method takes a single argument, which will be returned if the wrapped value is not present. This saves a call to `isPresent()` and will not throw any unchecked exceptions.

For returning primitive types, there are non-generic variants of Optional such as OptionalInt and OptionalDouble. You should favor these over using Optional<T> with boxed primitives, unless you have a specific need for boxed primitives.

Do not use Optional to return collections or arrays. Favor returning an empty collection/array.

And one additional caveat:

Do not use Optional or its variants if you’re trying to avoid heap allocations.

That’s all! If you feel like I’ve missed something, feel free to comment.