Optional.orElse() vs Optional.orElseGet()

Recently, I upgraded my project to Java 8 and enjoy to explorer new syntax more like Ruby or Scala.
Today, there was annoyed bug found in my code which is subtle to understand in documentation.

See following codes

@Test
public void jdk8OptionalTest() {
    Optional<String> s = Optional.of("Value's supposed to be");
    String ss = s.orElse(wontRunThis());
    System.out.println("optional returns " + ss);
}
 
private static String wontRunThis() {
    System.out.println("won't run this");
    return "something";
}

As expected ss="Value's supposed to be" as a result of the run.
The problem is that wontRunThis() was still executed although the Optional<String> wasn't empty.
It seems like JDK 8 treats wontRunThis() as literal and evaluates it regardless the condition.

A little bit wondering around this problem, I could fix the problem by using Optional.orElseGet()

@Test
public void jdk8OptionalTest2() {
    Optional<String> s = Optional.of("Value's supposed to be");
    String ss = s.orElseGet(() -> wontRunThis());
    System.out.println("optional returns " + ss);
}

So, the difference is that orElseGet() would execute the function only if Optional was empty.

Lesson learned. Optional.orElse() can be used to assigning literal value but we shouldn't expect a control flow with it.

Java 8 helps to reduce boilerplates but it, sometimes, behaves to different way from my expectation.
I'm still getting used with this new version of Java language.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License