Optional Best Practices
Optional was introduced in Java8 to solve the dreaded null reference problem.
If used correctly it solves the issue to a large extent.
This article attempts to give a few of the best practices of using the Optional.
Practice 1: Assignment
Do not assign null to an optional instance. Optional is a container which contains an instance of a class which may be absent. The optional itself should not be null
public Optional<milk> getMilk(Milktype milktype){
//logic for gtting milk
//if milk not found then
Optional<milk> maybeMilk = null;
return maybeMilk;
}
The above code is incorrect.
Correct code is to assign Optional.empty()
Optional<milk> maybeMilk = Otional.empty(); // correct way
return maybeMilk;
Practice 2: correctly use get()
Don’t use Optional.get() before ensuring that Optional does indeed have value. So:
A. first check presence of value using ifPresent().
B. Then use get().
Note: As much as possible don’t use get().
Practice 3: use of orElse()
If the value is absent, return the already constructed/computed default value in orElse().
So Avoid
Milk standardMilk = new Milk(MilkType.SKIMMED);
if maybeMilk.isPresent)(){
return maybeMilk.get();
}else{
return standardMilk;
}
Prefer
Milk standardMilk = new Milk(MilkType.SKIMMED);
maybeMilk.orElse(standardMilk);
Note that orElse() has performance impact as regardless of Optional has value or not, the orElse block will be evaluated. If you have implemented a cache and implementation like below
public class Cache{
public static Map<string, optional<user="">> userCache;
}</string,>
public User getUserDetails(String userId){
Optional<user> maybeUser = Cache.userCache.get(userId);
maybeUser.orElse(userRepo.get(userId));
}
In the case above the userRepo call will be made regardless of value present in the cache or not. It is always advisable to use orElseGet(). Note: map<string, optional<t=””>> itself is a bad practice as we will see later in the article. </string,></user>
Practice 4: Do not declare class fields as Optional
Optional is not serializable. Optional is not intended to be used as the property of a java bean or as a persistent type property.
So. Don’t use Optional as:
- Field/property of a class.
- Argument to the constructor.
- Argument to the setter method.
It is debatable if the Optional can be passed as an argument to a method. Please see this discussion and decide for yourself.
Practice 5: Do not mix Optional and Collection
- If returning a collection, do not bother about _Optional
_. If the collection does not have any value, return an empty collection. - Do not create a collection of optional e.g. map<string, optional<user=””>> is useless as in case of absence of a value, the map will not have a key. It is better to use collection constructs like rather than using Optionals. ```java User defaultUser = new User(Status.UNINITIALIZED); HashMap<string, user=””> userMap= ….//code to initialize userMap.getOrDefault(defaultUser);</string,></string,></collection>
```
Practice 6: Make generous use of Optional stream like methods
See Optionals for more details.