AI作成・独立検証済(有資格者監修なし)1Z0-829 対応
Optional(orElse の即時評価 vs orElseGet の遅延)難易度 高無料

次のコードの出力として正しいものを選べ。

 1  import java.util.*;
 2  public class Q7 {
 3      static String supply() {
 4          System.out.println("called");
 5          return "X";
 6      }
 7      public static void main(String[] a) {
 8          Optional<String> o = Optional.of("V");
 9          String r1 = o.orElse(supply());
10          String r2 = o.orElseGet(() -> supply());
11          System.out.println(r1 + " " + r2);
12      }
13  }
  1. Acalled 改行 V V
  2. BV V("called" は出力されない)
  3. Ccalled 改行 called 改行 V V
  4. Dcalled 改行 X X
正解・解説・誤答理由・ひっかけを見る▼ open
✓ 正解:AAI作成・独立検証済

解説

鍵は引数がいつ評価されるか

orElse(other) の引数 otherふつうのメソッド呼び出しの引数なので、 orElse を呼ぶ前に必ず評価される(Optional が値を持っていて使われなくても評価される)。 よって o.orElse(supply())supply()実行し("called" が出力される)、 その戻り "X" は捨てられ、Optional の中身 "V"r1 になる。

orElseGet(supplier)Supplier を受け取り、Optional が空のときだけ get() を呼ぶ(遅延評価)。 ここは値が有るので ラムダは呼ばれない("called" は増えない)。r2"V"

したがって出力は "called"(1回・orElse 由来)に続いて V V

各誤答が違う理由
  • BorElse(supply()) の引数は Optional が空でなくても必ず評価される。よって "called" が1回出る。
  • CorElseGet のラムダは Optional が空のときだけ実行される。ここは値が有るので呼ばれず、"called" は1回だけ。
  • DorElse/orElseGet は Optional が空のときだけ代替値を返す。値 "V" が有るので r1r2 とも "V"("X" は使われない)。
ひっかけ: 「値が有るなら or〜 の中身は使われない=評価もされない」という思い込み。orElse常に引数を評価する(副作用や重い処理があると無駄・危険)。だからデフォルト生成にコストがある時は orElseGet を使うのが定石。
実機確認の答え合わせ
出力:
called
V V
公式ドキュメント・関連Optional.orElse / orElseGet(SE17 API)
AIが作成し、独立した検証を経た解説です(有資格者による監修は経ていません)
この分野をもっと解いて、得点源に
Optional を含む問題を分野別に演習できます。
演習する →