I'm new to the Java optionals but I see this code written by another developer and I don't get it:
String t = null;
Optional.ofNullable("notnull")
.orElse(
Optional.ofNullable(t).orElseThrow(() -> new Exception("MyException"))
);
Why does this code throw the exception? Why does it even go to the "orElse" branch?
Is this because of some weird execution order? So the first optional's value is not set before the orElse branch is evaluated?
The orElse
stream is never invoked but the method itself is executed. This means that the method parameter is passed to it as well. So the part Optional.ofNullable(t).orElseThrow(() -> new Exception("MyException"))
is being called regardless of the value passed to the first Optional.ofNullable
call.
If you don't want this to happen you will need to pass a Supplier
like this:
String t = null;
Optional.ofNullable("notnull")
.orElseGet(
() -> Optional.ofNullable(t).orElseThrow(() -> new RuntimeException("MyException"))
);
The supplier is only invoked when the orElseGet
stream is invoked.
Note that you'll need a RuntimeException
instead of a checked exception in order to be able to break from the supplier.
That's because the code inside orElse()
will be always evaluated. In other words it will be executed even if you specify a non-empty Optional
, so that's why the Exception
will be thrown.
If you check the orElse()
section of Java Optional – orElse() vs orElseGet() article, you can see that in their example, where it says:
We can easily infer that the parameter of orElse() is evaluated even when having a non-empty Optional.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With