Search code examples
javalambdaoption-typelazy-evaluation

Why does the `orElseThrow()` method in Java take a `Supplier` as a parameter instead of an `Exception`?


Why does the orElseThrow() method in Java take a Supplier as a parameter instead of an Exception? This is the question and the best answer I have found is in here, stating

The overarching concept here is that by providing a method reference (or a function) it can be lazily initialized. No need to create Exception object if you don't need it. Create it only when you need it.

However, I still do not understand it. Why can't the object creation be lazy?


Solution

  • We're supposed to use orElseThrow() like this:

    anOptional.orElseThrow(() -> new Exception())
    

    Because the above does not create an Exception immediately: only if the optional is not present the Supplier lambda will be called, and at that moment the new exception will be instantiated. On the other hand, if we had this situation:

    anOptional.orElseThrow(new Exception())
    

    The exception would always be created, even if the optional was present, which would be costly. This is the reason why orElseThrow expects a Supplier<? extends X> with <X extends Throwable>, in other words: a lambda expression with no arguments that returns a new Throwable object when called.

    We say it's "lazy" because the lambda's body only gets evaluated at the last possible moment when it's truly needed, but if it's never needed the lambda's body will never be executed.