Optionals
created: 18 January 2021
revision: 1
Summary
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
- never refer a local var or a
- 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 =>
- Note:
- Rule3: prefer alternatives to
isPresent()
andget()
orElse
// a default valueorElseGet
// a supplier of default valueorElseGeThrow
// 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 ofOptional<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