AI作成・AIで再検証済(有資格者監修なし)1Z0-826-JPN 対応
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作成・AIで再検証済

解説

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

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" が有るので r1・r2 とも "V"("X" は使われない)。
ひっかけ: 「値が有るなら or〜 の中身は使われない=評価もされない」という思い込み。orElse は常に引数を評価する(副作用や重い処理があると無駄・危険)。だからデフォルト生成にコストがある時は orElseGet を使うのが定石。
実機確認の答え合わせ
出力:
called
V V
公式ドキュメント・関連Optional.orElse / orElseGet(SE17 API)↗
AIが作成し、別の手順のAIで誤りを点検した解説です(有資格者による監修は経ていません)

有資格者(著者)が監修した問題は、すべて無料サンプルとして公開しています。買う前に、その全部を実際に解いて解説まで読めます。有料で追加される問題はAIが作成したもので、有資格者の監修は入っていません。

この問題集の作り方

  1. 問題と解説はAIが作成しています。有資格者(著者)が監修した問題は、無料サンプルとして公開している分だけです。有料で追加される問題に監修は入っていません。
  2. 各問に、公式ドキュメントの出典リンクを付けています。書いてあることは、出典に当たって確かめられます。
  3. 誤答の選択肢それぞれに、なぜ誤りなのかの理由を書いています。
  4. 解説に載せているコンパイル結果は、実際に javac を走らせた出力です。想定した挙動ではありません。
  5. 誤りを見つけたら報告できます。原則として無償で訂正・削除します。
  6. 各試験の運営団体とは無関係の非公式教材です。合格を保証するものではありません。
この分野をもっと解いて、得点源に
Optional を含む問題を分野別に演習できます。
演習する →