This repository explores the best practices for using the Optional
class in Java to handle potentially absent values. By following these guidelines, you can effectively leverage Optional
and improve the clarity and safety of your code.
-
Rule #1: Never, ever, use
null
for an optional variable or return value: Instead of usingnull
, embrace the use ofOptional
to indicate the absence of a value. This helps preventNullPointerExceptions
and promotes safer code. -
Rule #2: Never use
Optional.get()
unless you can prove that theOptional
is present: Avoid usingget()
, which can throw aNoSuchElementException
. Instead, use alternative methods likeorElse
,orElseGet
, ororElseThrow
to handle the absence of a value safely. -
Rule #3: Prefer alternatives to
Optional.isPresent()
andOptional.get()
: Instead of explicitly checking for presence withisPresent()
and accessing the value withget()
, use methods likeorElse
,orElseGet
,orElseThrow
, orifPresent
to handle the absence of a value more effectively. -
Rule #4: It’s generally a bad idea to create an
Optional
for method chaining: Avoid creating anOptional
solely for the purpose of method chaining. This can introduce unnecessary complexity and reduce code readability. UseOptional
where it makes sense in the broader context of your code. -
Rule #5: Be cautious with nested
Optional
chains: When nestingOptional
types or having intermediate results ofOptional<Optional<T>>
, the code becomes complex and harder to understand. Consider refactoring the logic to simplify it. -
Rule #6: Avoid using
Optional
in fields, method parameters, and collections: WhileOptional
is useful for return types, it is generally not recommended for fields, method parameters, or collections. UsingOptional
in these scenarios can complicate code and reduce performance. Stick to conventional null checks instead. -
Rule #7: Avoid using identity-sensitive operations on Optionals: Be careful when using identity-sensitive operations like
==
or!=
to compareOptional
instances.Optional
is value-based, not identity-based, so these operations might not yield the expected results.
Consider the following example that demonstrates the addition of Optional<BigDecimal>
values:
Optional<BigDecimal> firstNumber = Optional.of(new BigDecimal(10));
Optional<BigDecimal> secondNumber = Optional.of(new BigDecimal(12));
// After addition:
Optional<BigDecimal> result = firstNumber.flatMap(a ->
secondNumber.map(b -> a.add(b))
);
// If both numbers are present, add them
// If one of them is empty, treat it as zero and add it to the other
// If both are empty, return empty