It's been a while from the day when Java 8 was released and the entire world get access to new API, including new class
Optional.
Even if a lot of time already passed, the uncertainty on how and when to use
Optional still persist.
In past days, before Java 8 the developers would create a service which would looks something like following:
public class UserRepository {
public User findUserByName(String username) {
// ... Code which will find user
return user;
}
}
The code which consumes the result of above API should verify for
NULL if unwanted
NullPointerException is desired.
Unfortunately the missing verification brought a lot of issues and money lose during entire Java history.
So it looked like Java 8 brought us a silver bullet, or at least so think a lot of Java developers. Today the
UserRepository would look like following:
public class UserRepository {
public Optional<User> findUserByName(String username) {
// ... Code which will find user
return Optional.ofNullable(user);
}
}
So does the
Optional is really save us from
NullPointerException? is it a silver bullet?
The answer is NO!
Even with
Optional the consumer should take in consideration that
Optional may contain
NULL, so what is the difference between
User user = userRepository.findUserByName("John");
return user != null ? user.getFullName() : "";
and
Optional<User> user = userRepository.findUserByName("John");
return user.map(User::getFullName).orElse("");
Well those who are for using
Optional will say that in such way the API is telling to consumer that the returned object may be
NULL and it should be handled, but it does not save from such usage as
userRepository.findUserByName("John").get().getFullName();
It is not right, but I already see such code, so how is it preventing from stupidity? Shouldn't each Java developer know that any method may return a
NULL and verify it accordingly?
If Optional in such case plays as documentation, then Java already for long time has
- JavaDoc - where API developer can state what a possible return values
- @Nullable/@Nonnull and other such type annotations
- Modern IDE which may tell to developer that method may return a NULL and proper handling should be done.
Still the Optional is useful a lot!
It very much simplify the code when a chain of transformations should be done, like:
Optional.ofNullable(userRepository.findUserByName("John"))
.map(User::getFullName)
.map(String::trim)
.map(String::toUpperCase)
.orElse("");