Alok Ailawadi

https://alok-ailawadi.github.io/

Follow me on GitHub

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="">&gt; 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:

  1. Field/property of a class.
  2. Argument to the constructor.
  3. 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

  1. If returning a collection, do not bother about _Optional_. If the collection does not have any value, return an empty collection.
  2. 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.