This article discusses the use of Java Optional, its benefits, and potential drawbacks in handling null values.
Abstract
The article "4 Reasons Why You Should Use Java Optional — or Not?" explores the use of the Optional class in Java to handle null values and improve code readability. The author presents four scenarios where Optional can be used: as a method return type, wrapping getters, wrapping local variables for simple logic, and using Optional fields and method parameters. The article concludes that Optional can be a valuable tool when used appropriately, but its misuse can lead to code cluttering and performance issues.
Bullet points
The Optional class can be used to wrap data before returning to avoid classical null checks and some try-catch blocks.
Using Optional can lead to more fluent, functional code.
Abusive use of Optional can lead to a drop in performance and code cluttering.
Optional can be used as a method return type to indicate that the result can be null.
Wrapping getters in Optional can be a good practice for fields where null is a valid value from a business point of view.
Wrapping local variables in Optional just for leveraging its API for simple operations is considered an anti-pattern.
Optional is not meant to be used to wrap class fields or as a method parameter.
Using Optional appropriately can bring expressivity to the domain model and some degree of safety.
Misuse of Optional can lead to bad design and code cluttering.
Some developers believe that Optional should be completely avoided.
With solid rules established among the team and proper code reviews, Optional can be a great feature for Java Developers.
4 Reasons Why You Should Use Java Optional — or Not?
The battle was fierce. The developers were exhausted.
Arguments were fired both ways. Each side had piles of bodies lying on the ground, burned out or collapsed.
Wars were fought over emails, merge requests, and Zoom Calls, but there was no clear winner. Let’s settle the Battle Of Optional once and for all!
Overview
We can use the Optional class to wrap our data and avoid the classical null checks and some of the try-catch blocks.
As a result, we’ll be able to chain method calls and have more fluent, functional code.
On the other hand, using it abusively can lead to a drop in performance and code cluttering.
In this article, we’ll explore some common use cases where we need protection against null values. For each of them, we’ll decide if Optional can be used to simplify our code or if we should stick to the classical null checks.
PS: For the code snippets, we will use the AccountRepository class with the following methods:
public Account get(String username);
public Optional<Account> find(String username);
1. Optional as Method Return Type 👍
One way of using Optional would be to wrap data before returning - if it can potentially be null. This approach was quickly adopted by developers and frameworks such as SpringDataJPA.
As a result, the caller will be aware that the result can be null. Furthermore, this gives the caller some flexibility: for example, it allows him to easily throw a custom exception if the Optional is empty.
Furthermore, if we need to perform additional checks on the data retrieved, Optional provides a nice API for it.
Let’s look into some scenarios and compare the two solutions:
We can notice the expression of the if statement is growing and becoming harder to read. For these use-cases, we can leverage the filter and map methods from the Optional’s API.
2. Wrapping the Getters 👍
As we can notice from the code snippet above, the Account class exposes a getMembershipOptional() method.
Of course, this is not the actual getter or the membership field. But that’s just because I have used the same data model for all the examples. In a real project we’ll either have the classic getter or the one returning Optional, but not both.
Making the getters return Optional can be a good practice for the fields where null is a valid value from a business point of view.
Since this would help us enrich our domain model, we should not apply it to DTO objects. This way, we’ll also avoid potential serialization issues.
3. Wrapping Local Variables For Very Simple Logic👎
Wrapping variables in Optional just for leveraging its API for simple operations is starting to become a common anti-pattern.
For example, using Optional just to inline if statements:
Optional is not meant to be used to wrap class fields. This will lead to the creation of objects where they are not needed and, if used repeatedly, in a performance drop.
Besides, the Optional class is not serializable. Consequently, having Optional fields can cause serialization issues.
Moreover, using Optional as a method parameter can also be considered an anti-pattern.
Let’s assume we have the following method signature:
As we have seen together in this article, the Optional class can bring expressivity to our domain model (through getters) and some degree of safety.
Though, if it’s not properly used, it can lead to bad design and code cluttering. Consequently, there are developers sharing the opinion that it should be completely avoided.
My opinion is that with some solid rules established among the team and some proper code reviews, Optional can be a great feature for Java Developers.