Javaの資格試験取得のため勉強中なのですが、
Java14で正式導入された「switch式」がリリースされていることについて知らなかった&
思ったよりも便利だったので今更ですがざっくり調べてみました。

構文

switch (式){
    case : 処理 yield 戻す値;
    または
    case 定数 -> 処理 戻す値;
}
  • :を使用する場合は処理の後に yield に続けて戻す値を指定する必要があります。
  • ->を使用する場合は処理の後に戻す値を指定する必要があります。
     また、条件合致後の処理が複数ある場合には {} 内に yield を用意して戻す値を指定する。
  • switch文は必ず値が必要となるためdefaultの処理は省略できません。

例文

public class Main {
	public static void main(String[] args) {
		int month = 2;
		System.out.println(month + " : " +
			switch (month) {
				case 12, 1, 2:  yield "Winter";
				case 3, 4, 5:   yield "Spring";
				case 6, 7, 8:   yield "Summer";
				case 9, 10, 11: yield "Autumn";
				default:        yield "N/A";
			});
		String val = switch (month) {
				case 12, 1, 2  -> "Winter";
				case 3, 4, 5   -> "Spring";
				case 6, 7, 8   -> "Summer";
				case 9, 10, 11 -> "Autumn";
				default        -> { System.out.println("N/A");
				                    yield "N/A"; }
			};
		System.out.println(month + " : " + val);
	}
}

// 実行結果
// 2 : Winter
// 2 : Winter

Switch式のメリットデメリット

メリット

今までのSwitch文から下記の点が改善されています。

  1. 可読性の向上
     短い記述で分岐処理を実装可能に
  2. 安全性の向上
     break忘れによるfallthroughを防げる
  3. 柔軟性の拡大
     yieldを使って複数行からも値を返せる
  4. コードの簡潔さ
     従来よりも明快なロジック表現が可能に

デメリット

下記の点が挙げられますが、個人的にはSwitch式を使うメリットのほうが大きいと思います。

  1. yieldを使用することで生まれる混乱
     yieldの導入は既存のbreakやreturnと記述を間違えるなどの混乱を招く可能性がある。
  2. パフォーマンス面の影響
     パフォーマンスの違いは使用する場面によるが、
     特に複数行のcaseブロックが多い場合に従来のSwitch文よりわずかに遅くなることがある。

※fallthroughとはcase文のbreakを省略した書き方です。
  breakは次のcase文の処理を実行したくない場合に記述します。
 そのため次のcase文の処理を続けて実行したい場合には、breakを省略します。

ざっくりSwitchの歴史

1. JavaのSwitch文(Java最初期)

 Switch文に関してはJDK1.0(1996年)から存在していましたが以下のような課題点がありました。

  • 各caseの最後にbreakが必要で、忘れると意図しないfallthroughが発生する
  • 1つのケースで複数の値を返すのが煩雑
  • 返り値がないため処理が長くなりがち

2. Switch式の登場(Java 12)

 Java12では従来のswitch文を改善するためにお試しでの機能としてswitch式が導入されました。
 これにより式形式でswitchを使い値を直接返すことが可能になりました。
 また、このプレビュー版はユーザーの使用感を確認するためのものでした。

  • switchが式(値を返す)として使えるようになる
  • 新しい構文である->が導入され、caseごとに明示的なブロックが不要になる
  • 従来のfallthroughを回避できる

例: Java12

int day = 3;
String dayType = switch (day) { case 1, 7 -> "Weekend";
                                default   -> "Weekday";};

3. Switch式の改良と正式採用(Java 14)

 Java14でswitch式は正式にJavaの言語仕様に組み込まれました。
 Java12のプレビュー機能から何点か改良が加えられています。

  • yieldキーワードの導入により、ブロック内の複数行の処理からも値を返せるように
    これにより従来のbreakのような誤用を減らし、より安全なコードが書けるようになりました。
  • yieldを使うことで、複数行の処理を持つcaseでも値を返すことができます
    これにより、より柔軟で読みやすいコードが書けるようになりました

例: Java14

int day = 3;
String dayType = switch (day) { case 1, 7 -> "Weekend"; 
                                default   -> {System.out.println("A weekday");
                                              yield "Weekday"; }};

4. その他の改善(Java 15以降)

 Java15以降ではswitch式のさらなる修正が続けられ、以下のような機能が改善されています。

  • nullの扱い:switchにnullを渡した場合、NullPointerExceptionを防ぐための対応が追加
  • パターンマッチング:case 句に型を指定可能に
    その他にも軽度な追加機能の修正が各バージョンにて行われています。

まとめ

Switch式はまだ改善の余地があるのかもしれませんが、
Java21がLTS版としてリリースされているので安定した機能として使用出来そうですね。
また、switch式でやれることもまだまだ増えていくのではないでしょうか。
古いシステムではバージョンが一桁台なんてことはいまだによくあるので、
バージョンアップの際に、余裕があればより直感的に見やすく、不具合の出にくいswitch式に変更するのはいかがでしょうか。