Why we need Java Optional?
A code example
String version = "UNKNOWN";
- less readable
- more lines of code
- easier to forget checking nulls
A better rewrite with Optional in Java 8
String name = computer.flatMap(Computer::getSoundcard)
How to use
Java 8's Optional was mainly intended for return values from methods, and not for properties of Java classes, as described in Optional in Java SE 8.
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.
- Not intended for use as a property of a Java Bean: not implement
- Not intended for use as a function parameter type. In comparison to nullable parameters Optional is more costly:
- conditional logic inside the methods is literally contra-productive
- need to pack an argument in an Optional, is suboptimal for the compiler, and does an unnecessary wrapping.
Optional unifies two states, which have to be unraveled. Hence better suited for result than input, for the complexity of the data flow.
Good vs Bad
- Force to check null value
- Remove nested null checks
- Provide default value and action
- Convenient Stream interface
- Optional::flatMap(), cascading Optional objects
- Optional::map(), extracting and transforming values
- Optional::filter(), conditional return
- Optional::orElse(), default values and actions
- Wrapper class, added layer of reference, which makes
- debugging stack traces may be slightly worse
- performance overhead on wrapping and unwrapping
- more complex class structure - being a wrapper class
- It's not serializable making it useless for many cases.
- Enforce conditional logic like
- Invariance. Certain operations become cumbersome when the actual value type is pushed into a generic type argument.
Optional::flatMap() vs Optional::map()
They both apply a mapper function and return an Optional.
But the mapper function is different. After applying mapper, map() also warps the result in an Optional.
flatMap() takes in
Function<? super T, Optional<U>> mapper, the mapper expects an Optional typed output.
It only does
map() takes in
Function<? super T, ? extends U> mapper, the mapper expects an U typed output.
Java 9’s Optional::stream
// In Java 8