本ページはプロモーションが含まれています

Java入門

Java yield入門|switch式での使い方とreturnとの違いをコード付き解説

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

Javaのyieldは、switch式の中から値を返すために使うキーワードです。Java 14で正式導入され、従来のswitch文で必要だったbreakの書き忘れバグや、冗長な変数宣言を一掃できます。

この記事では、yieldの基本的な仕組みからreturnとの明確な違い、アロー構文との使い分け、実務で使えるコードサンプルまでを体系的に解説します。

私もJava 14(2020年)でyieldが導入された当初は、従来のswitch文との違いに少し戸惑った経験があります。しかし、yieldの仕組みと利点を理解してからは、コードの可読性が劇的に向上しました。

Javaのyieldとは?

Javaのyieldは、switch式の中から値を返すために使われるキーワードです。Java 13でswitch文が「式」として拡張された際にプレビュー機能として導入され、Java 14(2020年3月)で正式な機能となりました。導入から6年が経過し、現在では広く使われています。

従来のswitchは「文(Statement)」であり、処理を実行するだけでした。しかし、新しいswitch「式(Expression)」は、処理の結果として値を生成できます。

yieldは、switch式の値を「産出する」または「提供する」という役割を担います。yieldにより、breakの書き忘れによるフォールスルーバグが構造的に起きないコードを書けるようになりました。

yieldが登場した背景(Java 14で導入された理由)

なぜyieldswitch式が導入されたのか。その答えは、従来のswitch文が抱えていた2つの課題にあります。

従来のswitch文には、主に2つの課題がありました。

  1. breakの書き忘れによるバグ
    caseごとにbreakを書き忘れると、処理が次のcaseに突き抜けてしまう「フォールスルー(処理が次のcaseに流れ落ちてしまう現象)」が起こります。フォールスルーは意図しないバグの温床として、多くの開発者を悩ませてきました。
  2. コードがムダに長くなる問題
    switch文の結果を外部の変数に代入する場合、まず変数を宣言し、各caseで代入処理を書く必要がありました。変数宣言と代入が分離するため、コードが長くなり、可読性が低下する傾向があったのです。

2つの課題を解決し、より安全で表現力豊かなコードを書けるようにするために、switch式とyieldが導入されました。switch式では、すべてのcaseを網羅することが強制されるため、バグが入り込む余地が減ります。

yieldと従来のreturnとの違い

yieldreturnは、どちらも値を返すキーワードですが、役割の範囲がまったく異なります。

  • return: メソッド全体の処理を終了し、値を呼び出し元に返します。returnが実行された時点で、そのメソッドは完全に終了
  • yield: switch式の中から値を返すだけで、メソッドの処理は終了しません。switch式の評価が完了した後も、メソッド内の後続の処理は続行される

つまり、スコープが違うと覚えておきましょう。returnはメソッド全体、yieldは自身が含まれるswitch式だけが対象です。

yield・return・breakの違い早見表

3つのキーワードの違いを表で整理すると、役割の範囲が一目でわかります。

項目yieldreturnbreak
スコープswitch式のみメソッド全体switch文/ループ
値を返せるか○(switch式の結果)○(メソッドの戻り値)×
メソッドが終了するかしないするしない
フォールスルー防止○(式なので不要)○(メソッド終了)○(明示的に記述)
使える場所switch式の中メソッド内どこでもswitch文/ループ内

迷ったら「switch式で値を返したいならyield、メソッドごと終了するならreturn、switch文やループを抜けるだけならbreak」と覚えましょう。

switch式でのyieldの使い方

それでは、yieldをどのように使うのかを具体的に見ていきましょう。yieldswitch式の中で、特定のcaseが返す値を指定するために使用します。

switch式とyieldの組み合わせ例

yieldは、caseの処理が複数行にわたる場合に使われるのが一般的です。以下のコード例はJava 14以降で動作します。caseの後にコロン:を書き、波括弧{}で囲んだブロック内で処理を記述し、最後にyieldで返す値を指定します。

// 曜日(enum)に基づいてメッセージを返す例
DayOfWeek day = DayOfWeek.MONDAY;
String message = switch (day) {
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "平日です。頑張りましょう!";
    case SATURDAY, SUNDAY -> {
        System.out.println("休日が検出されました。");
        // 何か別の処理...
        yield "休日です。ゆっくり休みましょう!";
    }
    // defaultは不要 (enumの全パターンを網羅しているため)
};
System.out.println(message);

上のコードでは、土曜日または日曜日の場合に、コンソールへの出力処理を行った後、yieldを使って文字列を返しています。一方、平日のcaseのように処理が1行で済む場合は、アロー->を使ってより簡潔に書けます。

あわせて読む

従来のswitch文との違いを比較

同じ処理を従来のswitch文で書いた場合と比較すると、yieldを使ったswitch式のメリットがより明確になります。

従来のswitch文を使ったコード:

DayOfWeek day = DayOfWeek.MONDAY;
String message; // 外部で変数を宣言
switch (day) {
    case MONDAY:
    case TUESDAY:
    case WEDNESDAY:
    case THURSDAY:
    case FRIDAY:
        message = "平日です。頑張りましょう!";
        break; // breakが必須
    case SATURDAY:
    case SUNDAY:
        System.out.println("休日が検出されました。");
        // 何か別の処理...
        message = "休日です。ゆっくり休みましょう!";
        break; // breakが必須
    default:
        // 本来は到達しないが、念のため例外処理
        throw new IllegalStateException("不正な曜日: " + day);
}
System.out.println(message);

switch式とyieldを使ったコード(再掲):

DayOfWeek day = DayOfWeek.MONDAY;
String message = switch (day) { // 式なので直接変数に代入できる
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "平日です。頑張りましょう!";
    case SATURDAY, SUNDAY -> {
        System.out.println("休日が検出されました。");
        yield "休日です。ゆっくり休みましょう!"; // breakは不要
    }
};
System.out.println(message);

比較すると、switch式とyieldを使ったコードの方が、以下の点で優れていることがわかります。

  • breakが不要: breakの書き忘れによるバグの心配がありません。
  • コードが簡潔: 変数をswitchの外で宣言する必要がなく、直接代入できるため、全体的にすっきりしています。
  • 網羅性の保証: enumの全パターンをcaseで網羅している場合、defaultが不要になります。もし網羅していないとコンパイルエラーになるため、記述漏れを防げます。

yieldを使うことで、より安全で読みやすいコードを実現できるのです。

実務では、既存コードベースがJava 14以降であれば、新規コードはswitch式を優先的に使うことをおすすめします。特にenumを返す処理やステータスコードの分岐では、switch式の網羅性チェックがコンパイル時にバグを防いでくれます。ただし、チーム内でswitch式に馴染みがないメンバーがいる場合は、コードレビューで混乱を招かないよう、チーム内で使い方のガイドラインを事前に合意しておくと良いでしょう。

実務で使えるyieldのコード例(HTTPステータス判定)

もう少し実践的な例を見てみましょう。HTTPステータスコードに応じて、クライアントに返すメッセージのカテゴリを判定する処理を考えます。

int statusCode = 200;
String category = switch (statusCode) {
    case 200, 201, 204 -> "成功";
    case 400, 401, 403, 404 -> {
        // 400番台のエラーはログに記録するなどの追加処理
        logError("クライアントエラーが発生しました: " + statusCode);
        yield "クライアントエラー";
    }
    case 500, 503 -> {
        // 500番台のエラーはより詳細なログを残す
        logServerError("サーバーエラーが発生しました: " + statusCode, new Exception());
        yield "サーバーエラー";
    }
    default -> {
        // 想定外のコードは不明として扱う
        logWarning("不明なステータスコード: " + statusCode);
        yield "不明";
    }
};

System.out.println("ステータスカテゴリ: " + category);

yieldを使えば、各case内でログ出力などの追加処理を実行しつつ、最終的な値をswitch式の結果として返せます。処理と値の返却を1つのcaseブロックにまとめられる点が便利です。

yieldを使うときの注意点

yieldは便利な機能ですが、使い方を誤るとコンパイルエラーになります。以下の3つの注意点を押さえておきましょう。

switch「文」では使えないことに注意

最も重要な注意点は、yieldswitch「式」専用のキーワードである、という点です。値を返さない従来のswitch「文」の構文の中でyieldを使おうとすると、コンパイルエラーになります。

コンパイルエラーになる例:

int num = 1;

// これは値を返さない「文」なので、yieldは使えない
switch (num) {
    case 1:
        System.out.println("1です");
        yield 1; // ここでコンパイルエラー!
        break;
    default:
        System.out.println("その他");
        break;
}

switchが式として扱われるのは、switchブロック全体が変数の代入やreturnの対象になっている場合です。yieldは、switch式が返す値を指定するためだけに存在します。

可読性の観点からの使い分け

switch式には、yieldを使う構文と、アロー->を使う構文の2種類があります。可読性の観点から使い分けましょう。

  • アロー (->) を使うべきケース
    caseの処理が1行で終わるなら、アローが簡潔です。
    例: case MONDAY -> "平日";
  • yield を使うべきケース
    値を返す前にログ出力などの処理が必要なとき、波括弧{}ブロック内でyieldを使います。
    例: case SATURDAY -> { System.out.println("ログ出力"); yield "休日"; }

処理内容に応じて適切な構文を選択することで、コードの意図が伝わりやすくなります。

筆者の経験上、yieldが必要になるケースは全体の2〜3割程度です。ほとんどのcaseは1行で済むためアロー構文で十分で、ログ出力やバリデーションなど副作用を伴う処理がある場合にだけyieldを使う、という運用が実務ではうまく機能しています。

Java 13以前では使えない — バージョン互換性の注意

yieldはJava 14で正式に導入された機能です。2026年時点の最新LTSはJava 21で、ほとんどの新規プロジェクトではyieldが利用可能です。プロジェクトで使っているJavaのバージョンが13以前なら、yieldおよびswitch式は使えません。

チームで開発している場合は、プロジェクト全体のJavaバージョンを確認することが必要です。古いバージョンで運用されているシステムに、安易にyieldを使ったコードを追加すると、ビルドエラーの原因となります。

yieldという単語は、Java 13までは変数名に使えました。Java 14以降では予約語(キーワード)になったため、変数名には使えません。古いコードを新しいバージョンに移行する際は、この点にも注意が必要です。

なお、Java 17以降ではswitch式にパターンマッチングが追加され、型による分岐も可能になっています。yieldを理解しておくことが、これらの新機能を活用するための土台になります。

まとめ — yieldを正しく理解して効率的に使おう

yieldの要点を振り返ります。

  • yieldは、switch式の中から値を返すためのキーワードです。
  • 従来のswitch文が抱えていたbreakの書き忘れやコードのムダの多さといった問題を解決します。
  • returnがメソッド全体を終了させるのに対し、yieldswitch式の結果を返すだけで、メソッドの処理は続行されます。
  • yieldは値を返さないswitch「文」では使えず、switch「式」の中でのみ利用可能です。

yieldを適切に使いこなすことで、Javaコードはより安全で、簡潔かつ可読性の高いものへと進化します。

  • この記事を書いた人
  • 最新記事

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

-Java入門