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("");
No comments:
Post a Comment