Summary

(Marks, n.d.)

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.

  • Rule1: never use null for an Optional variable or return value
    • never refer a local var or a null, it defeats the purpose of optional
  • Rule2: never use optional.get unless you can prove that the optional is Present
    • Note: opt.isPresent() … it is hardly any better than checking for null =>
  • Rule3: prefer alternatives to isPresent() and get()
    • orElse // a default value
    • orElseGet // a supplier of default value
    • orElseGeThrow
// REPLACE THIS:
opt.IsPresent() : opt.get()getName() : "UNKNOWN";
// WHIT THIS:
opt.map(Customer::getName).orElse("UNKNOWN");
Optional<Task> oTask = getTask(...);
if(oTaks.isPresent()) { executor.runTaks(oTaks.get());
// better
getTask(...).ifPresent(task -> executor.runTaks(task));
// best
getTask(...).ifPresent(executor::runTask)
  • Rule4: It is generally a bad idea to create an Optional for the specific purpose of chaining methods from it to get a value:
return Optional.ofNullable(s).orElseGet(this::getDefault); // BAD
return (s != null) ? s : getDefault(); // GOOD
  • Rule5: If an Optional chain is nested or has an intermediate result of Optional<Optional<T>>, it is probably too complex.

  • Rule6: Avoid using Optional in fields, method parameters, and collections. Remember:
    • Optional is box!
    • Consumes 16 bytes,
    • Potentially adds GC pressure,
    • A single Optional is OK, but if too many (stored in structures) could lead to performance problems
    • Optional is not a NULL replacement
    • Optional is not serializable
  • Rule7: Avoid using identity-sensitive operations in Optionals

References

  • Marks, S. Optional - The Mother of All Bikesheds. https://www.youtube.com/watch?v=Ej0sss6cq14