Java Optional working of orElse is not as if else
Use orElseGet()
to avoid evaluating getDefaultPoJo()
when the Optional
is not empty:
PoJo poJo1=getNullPoJo().orElseGet(() -> getDefaultPoJo());
PoJo poJo2=getLoadedPoJo().orElseGet(() -> getDefaultPoJo());
getNullPoJo().orElse(getDefaultPoJo());
It's a method chain, and every method in this chain will get executed, no matter how the underlying API is supposed to work.
1) getNullPoJo()
2) r = getDefaultPoJo()
3) orElse(r)
In order to execute a method, its actual parameters must be evaluated. To call orElse(getDefaultPoJo())
, getDefaultPoJo()
must be invoked as well. That's the reason you are getting more than you expected.
Usually, you will see
.orElse(null);
.orElse(defaultValue);
where null
, and defaultValue
are predefined values that don't require any calculations.
On the other hand, we write
.orElseGet(() -> generateDefaultValue());
.orElseGet(() -> calculateDefaultOutcome());
where generateDefaultValue
and calculateDefaultOutcome
are methods that do perform some calculations (intensive ones or ones we don't want to execute until the right moment [your case]).
Compare,
.orElseGet(() -> createDefaultPoJo());
.orElse(DEFAULT_POJO);
where DEFAULT_POJO
is a variable initialised prior to this method call, and createDefaultPoJo()
is a method that creates a default instance every time it gets called.
The output is correct, Optional.orElse()
will allways execute the else-action. (the expression you provide) Use orElseGet()
-which only calls the function if Optional.isPresent == false
- for your desired output:
Difference between `Optional.orElse()` and `Optional.orElseGet()`
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#orElseGet-java.util.function.Supplier-