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
nullfor an optional variable or return value: Instead of usingnull, embrace the use ofOptionalto indicate the absence of a value. This helps preventNullPointerExceptionsand promotes safer code. -
Rule #2: Never use
Optional.get()unless you can prove that theOptionalis present: Avoid usingget(), which can throw aNoSuchElementException. Instead, use alternative methods likeorElse,orElseGet, ororElseThrowto 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, orifPresentto handle the absence of a value more effectively. -
Rule #4: It’s generally a bad idea to create an
Optionalfor method chaining: Avoid creating anOptionalsolely for the purpose of method chaining. This can introduce unnecessary complexity and reduce code readability. UseOptionalwhere it makes sense in the broader context of your code. -
Rule #5: Be cautious with nested
Optionalchains: When nestingOptionaltypes 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
Optionalin fields, method parameters, and collections: WhileOptionalis useful for return types, it is generally not recommended for fields, method parameters, or collections. UsingOptionalin 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 compareOptionalinstances.Optionalis 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