inspired by Java Champion Mohamed Taman
Original article: Do you use the Optional class as it should be?
=> 25+ recipes to use Optional class effectively which is not optional
Video => https://youtu.be/5kdBZsB563A
Agenda
- How to survive from null pointer exceptions (NPE)
- What to return/set when there is no value present?
- How to consume optional values effectively?
- How to avoid Optional anti-patterns?
- How to use Optional professionally?
❔❓ Question #1: oh, I am getting null even when I use Optional?
👉Code recipe #1
//Avoid
Never assign Null to an optional variable.
//Prefer
Initialize an empty() optional variable and do not use null.
👉Code recipe #2
//Avoid
Never call Optional.get() directly to get the value.
//Prefer
Check the value with Optional.isPresent() before calling Optional.get().
👉Code recipe #3
//Avoid
Don't use null directly when you have an Optional & need a null reference.
//Prefer
Use Optional.orElse(null) to return null.
❔❓ Question #2: What to do when no value is present? ☹
👉 Code recipe #4
// Avoid
Don't use isPresent()-get() pair for setting/returning a value.
// Prefer
Use Optional.orElse() as an elegant alternative to set/return an already-constructed default object.
👉 Code recipe #5
//Avoid
Don't use orElse() for setting/returning a computed value.
(Don't use neither isPresent/get).
//Prefer
Performance matters, use Optional.orELseGet() for setting/returning a computed value.
👉 Code recipe #6
//Avoid
Don't throw java.util.NoSuchElementException when there is no value using isPresent()-get().
//Prefer
Throw a java.util.NoSuchElementException exception via an elegant alternative orElseThrow().
// or Prefer
Throw an explicit exception via orElseThrow(Supplier
exceptionSupplier).
❔❓ Question #3: How to consume Optional effectively? 👌
👉 Code recipe #7
//Avoid
Don't use isPresent()-get() to do nothing if value is not present.
//Prefer
Use ifPresent() to consume Optional value if present or do nothing if not.
👉 Code recipe #8
//Avoid
Don't use isPresent()-get() to execute an Empty-Based action if value is not present.
//Prefer
Use ifPresentOrElse() to consume Optional value if present or execute an empty based action if not.
👉 Code recipe #9
//Avoid
Don't use isPresent()-get() to set/return the other Optional when no value is present.
//Prefer
// or Prefer
👉 Code recipe #10
//Avoid
Don't use isPresent()-get() with Lambdas
Example 1
// also avoid
Don't do this, it is breaking the chain.
// Prefer
Optional.orElse()/orElseXXX() are perfect with Lambdas.
// also Avoid
Don't check for value to throw an exception.
Example 2
//Prefer
Use .orElseThrow with lambdas.
👉 Code recipe 11
//Avoid
Don't overuse Optional by chaining its methods for the single purpose of getting value.
//Prefer
Avoid this practice and rely on simple and straightforward code.
❔❓ Question #4: How can I use Optional while designing my APIs? 🙇♂️
👉 Code recipe #12
//Avoid
Do NOT declare any field of type Optional.
Because it breaks serialization, it wastes memory heap space, and because Optional is to prevent null values or Entity fields can be null.
//Prefer
Optional doesn't implement Serializable. It is not intended for use as a property of a Java Bean.
👉 Code recipe #13
//Avoid
Do NOT use Optional in contructors arguments.
It's nonsense, because Optional means it might exist or not WHEN you RETURN it as a type, NOT when you pass it.
//Prefer
Optional is not intended for use in constructors' arguments.
If you wanna check the nullability, do it in a getter with Optional.ofNullable().
👉 Code recipe #14
//Avoid
Using Optional in setters is another anti-pattern.
Same rule than constructors parameters.
//Prefer
Do NOT use Optional in setters arguments.
Concentrate your focus on the getter.
👉 Code recipe #15
//Avoid
Using Optional in methods arguments is another common mistake.
//Prefer
Do NOT use Optional in methods arguments.
// also Prefer
Also, prefer to rely on NullPointerException.
// also Prefer
Also, prefer to avoid NullPointerException and use IllegalArgumentException or other exceptions.
How to use this? This is very easy:
👉 Code recipe #16
//Avoid
Do not use Optional to return empty Collections or Arrays.
// Prefer
Rely on Collections.emptyList(), emptyMap(), emptySet().
👉 Code recipe #17
//Avoid using Optional in Collections.
// Prefer
Do not introduce another layer into your Map, it is costly, and it strikes performance.
// Prefer
You can also rely on other approaches, such as
- containsKey
- () method
- Trivial implementation by extending HashMap
- Java 8 computeIfAbsent() method
- Apache Commons DefaultedMap
// Avoid, this is even worse
This strikes performance.
👉 Code recipe #18
Use Optional.ofNullable() instead of Optional.of()
//Avoid
//Prefer
Use Optional.of() instead of Optional.ofNullable() for constructed values (like constants).
//Avoid
//Prefer
👉 Code recipe #19
//Avoid
Avoid Optional
and choose a non-generci Optional.
//Prefer
To avoid boxing and unboxing, use non-generic Optional.
❔❓ Question #5: I like Optional, what can I do more?