Java’s Optional Does Not Supplant All Traditional if-null-else or if-not-null-else Checks
Java‘s addition of java.util.Optional has been welcome and had led to more fluent code for methods that cannot always return non-null
values. Unfortunately, Optional has been abused and one type of abuse has been overuse. I occasionally have run across code that makes use of Optional when there is no clear advantage over using null
directly.
A red flag that can tip off when Optional
is being used for no advantage over checking for null
directly is when calling code employs Optional.ofNullable(T) against the returned value from the method it has just invoked. As with all “red flags,” this doesn’t mean it’s necessarily a bad thing to pass the returned value from a method to Optional.ofNullable(T)
(in fact, it is necessary to pass to APIs expecting Optional
), but it is common for this approach to be used to provide no real value over using the returned value directly and checking it for null
.
Before Optional was available, code to check for null
returned from a method and acting one way for null
response and another way for non-null
response is shown next (all code snippets in this post are available on GitHub).
/** * Demonstrates approach to conditional based on {@code null} or * not {@code null} that is traditional pre-{@link Optional} approach. */ public void demonstrateWithoutOptional() { final Object returnObject = methodPotentiallyReturningNull(); if (returnObject == null) { out.println("The returned Object is null."); } else { out.println("The returned object is NOT null: " + returnObject); // code processing non-null return object goes here ... } }
For this basic conditional, it’s rarely necessary to involve Optional
. The next code snippet is representative of the type of code I’ve occassionally seen when the developer is trying to replace the explicit null
detection with use of Optional:
/** * Demonstrates using {@link Optional} in exactly the manner {@code null} * is often used (conditional on whether the returned value is empty or * not versus on whether the returned value is {@code null} or not). */ public void demonstrateOptionalUsedLikeNullUsed() { final Optional<Object> optionalReturn = Optional.ofNullable(methodPotentiallyReturningNull()); if (optionalReturn.isEmpty()) { out.println("The returned Object is empty."); } else { out.println("The returned Object is NOT empty: " + optionalReturn); // code processing non-null return object goes here ... } }
The paradigm in this code is essentially the same as the traditional null
-checking code, but uses Optional.isEmpty() to perform the same check. This approach does not add any readability or other advantage but does come at a small cost of an additional object instantiation and method call.
A variation of the above use of Optional
is to use its ifPresent(Consumer) method in conjunction with its isEmpty() method to form the same basic logic of doing one thing if the returned value is present and another thing if the returned value is empty. This is demonstrated in the following code.
/** * Demonstrates using {@link Optional} methods {@link Optional#ifPresent(Consumer)} * and {@link Optional#isEmpty()} in similar manner to traditional condition based * on {@code null} or not {@code null}. */ public void demonstrateOptionalIfPresentAndIsEmpty() { final Optional<Object> optionalReturn = Optional.ofNullable(methodPotentiallyReturningNull()); optionalReturn.ifPresent( (it) -> out.println("The returned Object is NOT empty: " + it)); if (optionalReturn.isEmpty()) { out.println("The returned object is empty."); } }
This code appears bit shorter than the traditional approach of checking the returned value directly for null
, but still comes at the cost of an extra object instantiation and requires two method invocations. Further, it just feels a bit weird to check first if the Optional is present and then immediately follow that with a check if it’s empty. Also, if the logic that needed to be performed was more complicated than writing out a message to standard output, this approach becomes less wieldy.
Conclusion
Code that handles a method’s return value and needs to do one thing if the returned value is null
and do another thing if the returned value is not null
will rarely enjoy any advantage of wrapping that returned value in Optional
simply to check whether it’s present or empty. The wrapping of the method’s returned value in an Optional
is likely only worth the costs if that Optional
is used within fluent chaining or APIs that work with Optional
.
Published on Java Code Geeks with permission by Dustin Marx, partner at our JCG program. See the original article here: Java’s Optional Does Not Supplant All Traditional if-null-else or if-not-null-else Checks Opinions expressed by Java Code Geeks contributors are their own. |
In general I support your statement, that Optional is not always the way to go. But your example is quite bad demonstrating this. For your case there exists ifPresentOrElse. Especially if you use method calls in the two cases, the readeability can be increased in my mind:
This also prevents the developer from using lengthy expressions inside the branches and create new methods for them instead.
hi,,
You are posting a very well article. thanks for the sharing. keep posting.
keep sharing
keep updating blogs
Nice and very useful article for java begginers. Java is trending language and your articles are easy to understand. Everything is clearly explained. Very useful article for begginers who want to build there career in programming..