Valid usage of Optional type in Java 8

I’ll take another swing at this.

Is this a valid usage? Yes, in the narrow sense that it compiles and produces the results that you’re expecting.

Is this intended usage? No. Now, sometimes things find usefulness beyond what they were originally for, and if this works out, great. But for Optional, we have found that usually things don’t work out very well.

Brian Goetz and I discussed some of the issues with Optional in our JavaOne 2015 talk, API Design With Java 8 Lambdas and Streams:

The primary use of Optional is as follows: (slide 36)

Optional is intended to provide a limited mechanism for library method return types where there is a clear need to represent “no result,” and where using null for that is overwhelmingly likely to cause errors.

The ability to chain methods from an Optional is undoubtedly very cool, and in some cases it reduces the clutter from conditional logic. But quite often this doesn’t work out. A typical code smell is, instead of the code using method chaining to handle an Optional returned from some method, it creates an Optional from something that’s nullable, in order to chain methods and avoid conditionals. Here’s an example of that in action (also from our presentation, slide 42):

// BAD
String process(String s) {
    return Optional.ofNullable(s).orElseGet(this::getDefault);
}

// GOOD
String process(String s) {
    return (s != null) ? s : getDefault();
}

The method that uses Optional is longer, and most people find it more obscure than the conventional code. Not only that, it creates extra garbage for no good reason.

Bottom line: just because you can do something doesn’t mean that you should do it.

Leave a Comment