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.