Avoid using Optional to hide a Null-checks
Using an Optional
to hide a null-check - is an Antipattern.
There's nothing wrong with implicit null-checks e.g. if (something == null)
and more over Optional
wasn't designed to perform null-checks.
Here's a quote from the answer by Stuart Marks, Java and OpenJDK developer:
The primary use of Optional is as follows: (slide 36)
Optional
is intended to provide a limited mechanism for library method
return types where there is a clear need to represent "no result," and
where using null
for that is overwhelmingly likely to cause errors.
The ability to chain methods from an Optional
is undoubtedly very
cool, and in some cases it reduces the clutter from conditional logic.
But quite often this doesn't work out. A typical code smell is,
instead of the code using method chaining to handle an Optional
returned from some method, it creates an Optional from something
that's nullable, in order to chain methods and avoid conditionals.
(the emphasis is mine)
From the quote above, it's clear that Optional
was introduced in the JDK to provide a limited mechanism for return types. Any other cases like using optional as a field, storing it into a Collection, creating an optional to substitute a null-check or/and in order to chain methods on it are considered to be an abuse of Optional
.
Also have a look at another answer by Stuart Marks: Should Optional.ofNullable() be used for null check?
That said, the cleaner way of retrieving employee by id
, when id
in the request object can be null
would be the following:
public Employee getEmployeeById(Request request) {
Long id = request.getId();
if (id == null) return new Employee();
return employeeRepository.findById(id)
.orElse(new Employee());
}
If fill uncomfortable that new Employee()
appears twice in the code, then you can reimplement it like that:
public Employee getEmployeeById(Request request) {
Long id = request.getId();
Optional<Employee> result = Optional.empty();
if (id != null) result = employeeRepository.findById(id);
return id == null || result.isEmpty() ? new Employee() : result.get();
}