orElseとorElseGetの違い|Java Gold SE17頻出問題を解説

【図解】Java Gold SE17頻出問題「orElseとorElseGetの違い」を解説。左側は「orElse(常に評価)」でisPresent()の真偽に関わらず引数が常に実行される仕組み、右側は「orElseGet(必要な時だけ評価)」でisPresent()=falseの時のみ実行される仕組みを、フローチャートで対比。中央には時計、猫のキャラクター、下部には未経験からGold合格までの5ステップのロードマップが手書き風イラストで図解されたアイキャッチ画像。

Java Gold SE17の試験では、Optionalのメソッドを使ったコード読解問題が頻出です。中でもorElseとorElseGetは見た目がよく似ているため、引っかけ問題として狙われやすいテーマです。この記事では「コードを実行すると何が出力されるか」という形式でorElseとorElseGetの違いを解説します。「なんとなく使い分けている」という状態から、試験で確実に得点できるレベルまで理解を深めましょう。

目次

この記事でわかること

  • orElseとorElseGetの引数が評価されるタイミングの違い
  • Java Goldで狙われる引っかけポイント
  • コード問題の正しい解き方
  • 実務でorElseGetを使うべき場面

1. Java GoldでOptionalが狙われる理由

OptionalはJava 8から導入されたnull安全のためのクラスです。ただし、Java Gold試験ではnullの扱い方だけでなく、メソッドごとの挙動の細かい違いが問われます。特にorElse・orElseGet・orElseThrowの3つは、似た名前でありながら動作が異なるため、出題されやすいテーマです。

試験で問われるのは主に2パターンです。まず「Optionalに値がある場合と空の場合で出力結果がどう変わるか」、次に「引数として渡したメソッドがいつ実行されるか」です。後者が今回のメインテーマです。

2. メイン問題:このコードの出力結果は?

まず以下のコードを見てください。

import java.util.Optional;

public class Main {
    static String createDefault() {
        System.out.println("default");
        return "デフォルト値";
    }

    public static void main(String[] args) {
        Optional<String> opt = Optional.of("Java");
        String result = opt.orElse(createDefault());
        System.out.println(result);
    }
}

このコードを実行したとき、出力される結果はどれですか?

A. Javaのみ出力される
B. defaultJavaの順で出力される
C. Javadefaultの順で出力される
D. デフォルト値のみ出力される

正解

正解:B「default」→「Java」の順で出力される

3. 詳細解説:orElseは引数が必ず評価される

「Optionalに”Java”という値が入っているのに、なぜcreateDefault()が実行されるの?」と思った方、それがまさにorElseの落とし穴です。

Javaはメソッドの引数をメソッドが呼ばれる前に評価します。つまり、opt.orElse(createDefault())というコードでは、orElseが呼ばれる前にcreateDefault()が実行されます。その結果、Optionalに値があってもなくても、createDefault()は必ず実行されます。

コードの実行順序を整理すると以下の通りです。

  1. 引数のcreateDefault()が評価される→「default」が出力され「デフォルト値」が返る
  2. opt.orElse("デフォルト値")が実行される
  3. optに値(”Java”)があるため、”Java”が返される
  4. System.out.println("Java")が実行される

したがって、出力は「default」→「Java」の順になります。戻り値だけ見ると「JavaがあるからJavaが返る」と正しく判断できても、副作用(System.out.println)の実行タイミングを見落とすと間違えます。これがJava Goldで狙われるポイントです。

4. orElseGetに変えたらどうなる?類題で確認

次に、同じコードのorElseをorElseGetに変えた場合を見てみましょう。

import java.util.Optional;

public class Main {
    static String createDefault() {
        System.out.println("default");
        return "デフォルト値";
    }

    public static void main(String[] args) {
        Optional<String> opt = Optional.of("Java");
        String result = opt.orElseGet(() -> createDefault());
        System.out.println(result);
    }
}

このコードの出力結果は「Java」のみです。orElseGetの引数はSupplier(ラムダ式)です。Supplierは「呼ばれたときに初めて実行される」関数型インターフェースです。つまり、() -> createDefault()というラムダ式は、Optionalが空の場合にだけ実行されます。今回はOptionalに”Java”という値があるため、ラムダ式は実行されず、createDefault()も呼ばれません。結果として「Java」だけが出力されます。

5. orElse・orElseGet・orElseThrowの違い比較表

メソッド引数の型引数が評価されるタイミング値がある場合空の場合
orElse(T)値(T型)必ず評価されるOptionalの値を返す引数の値を返す
orElseGet(Supplier)Supplier<T>空の場合だけ実行されるOptionalの値を返すSupplierの結果を返す
orElseThrow(Supplier)Supplier<Exception>空の場合だけ実行されるOptionalの値を返す例外をスローする

6. Java Gold本番での見抜き方

チェック①:orElseの引数にメソッド呼び出しがあるか確認する

orElse(someMethod())のように引数にメソッド呼び出しがある場合、Optionalに値があってもsomeMethod()は実行されます。副作用(出力・例外など)があるメソッドなら、必ず結果に影響します。

チェック②:orElseGetの引数はラムダ式かどうか確認する

orElseGet(() -> someMethod())のようにラムダ式になっている場合、Optionalが空のときだけsomeMethod()が実行されます。ラムダ式かどうかを見分けることが正解への第一歩です。

チェック③:副作用があるか確認する

System.out.println・例外スロー・DB更新などの副作用がある処理を引数に渡しているかを確認します。副作用がある場合、評価タイミングが出力結果に直接影響するため、見落とすと誤答につながります。

7. 実務目線の補足:orElseGetを使うべき場面

orElseの引数に重い処理(DBアクセス・外部API呼び出し・複雑な計算)を渡すと、Optionalに値があっても必ず実行されてしまいます。これはパフォーマンスの無駄につながります。一方、orElseGetはOptionalが空の場合にだけ実行されるため、重い処理を遅延実行したい場面に適しています。

  • orElseを使う場面:固定の文字列や定数など、評価コストがほぼゼロの値を返す場合
  • orElseGetを使う場面:DBアクセス・外部API・重い計算など、コストが高い処理をデフォルト値として使う場合

Optionalの詳細な仕様はOracle公式 Optional API(Java SE 17)で確認できます。

まとめ:orElseとorElseGetの違いを3行で覚える

  • orElseは引数が必ず評価される:Optionalに値があっても引数のメソッドは実行される
  • orElseGetは空の場合だけ実行される:SupplierはOptionalがemptyのときだけ呼ばれる
  • Java Goldでは副作用のある引数が引っかけとして使われる:出力や例外など副作用がある処理に注意する

Java Gold SE17の全体的な勉強法についてはJava Gold SE17対応 勉強法ロードマップも参考にしてください。またコード読解問題をさらに練習したい方はJava Gold SE17無料問題集もあわせてご覧ください。StreamのAPIについてはJava Gold SE17 Streamのdistinct・sorted・limitの解説も参考にしてください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

tibiyaのアバター tibiya ITエンジニア

文系卒エンジニア(8年目)
Java / JavaScript / C# を中心に業務システム開発を経験。
Java資格・IT就活・文系エンジニアの実体験を発信しています。

コメント

コメントする

目次