orElse() vs orElseGet() vs orElseThrow()
Fast recall
Quick revision
Core answer
orElse(T) receives an eagerly evaluated fallback value, while orElseGet(Supplier) calls its supplier only when the Optional is empty. Java 8 provides orElseThrow(Supplier extends X>) for a chosen exception. The no-argument orElseThrow() overload was added in Java 10 and throws NoSuchElementException when empty.Whether you understand eager fallback values, lazy suppliers, and the Java-version difference between the two `orElseThrow` forms.
Passing a method call with side effects to `orElse` and assuming it runs only when the Optional is empty.
Show the evaluation order with a small example and state that Java 8 has the exception-supplier form, while no-arg `orElseThrow()` arrived in Java 10.
Interview-ready guide
Interview answer
The main difference is evaluation timing. orElse(value) receives a value whose expression Java has already evaluated, so orElse(loadDefault()) calls loadDefault even when the Optional is present. orElseGet(supplier) calls the supplier only when the Optional is empty, which suits fallback work that should be deferred. orElseThrow expresses that absence is an error. In Java 8 I use orElseThrow(() -> new UserNotFoundException(id)); the no-argument overload was added in Java 10 and throws NoSuchElementException. For a ready constant such as "Guest", orElse remains the simplest choice.
orElse() vs orElseGet() vs orElseThrow()
Direct Answer
orElse(T) receives an eagerly evaluated fallback value, while orElseGet(Supplier<T>) calls its supplier only when the Optional is empty. Java 8 provides orElseThrow(Supplier<? extends X>) for a chosen exception. The no-argument orElseThrow() overload was added in Java 10 and throws NoSuchElementException when empty.
Common Mistakes & Pitfalls
- Assuming
orElseis lazy:orElse(repository.findDefaultUser())invokes the repository beforeorElsecan inspect the Optional. - Using a supplier where a value is clearer:
orElseGet(() -> "Guest")works, butorElse("Guest")expresses a constant fallback directly. - Ignoring the supplier's declared type:
Supplier<T>does not declare arbitrary checked exceptions, so anorElseGetlambda cannot simply throw one unless the surrounding type system permits it. - Forgetting the Java version: the exception-supplier overload exists in Java 8; no-arg
orElseThrow()does not.
Check your understanding
Answer these without looking back at the article.
- When would orElse() cause a performance issue?
- What is the no-arg orElseThrow() equivalent to?
- Can orElseGet() be used to return a null default?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.