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文から下記の点が改善されています。
- 可読性の向上
短い記述で分岐処理を実装可能に
- 安全性の向上
break忘れによるfallthroughを防げる
- 柔軟性の拡大
yieldを使って複数行からも値を返せる
- コードの簡潔さ
従来よりも明快なロジック表現が可能に
デメリット
下記の点が挙げられますが、個人的にはSwitch式を使うメリットのほうが大きいと思います。
- yieldを使用することで生まれる混乱
yieldの導入は既存のbreakやreturnと記述を間違えるなどの混乱を招く可能性がある。
- パフォーマンス面の影響
パフォーマンスの違いは使用する場面によるが、
特に複数行の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式に変更するのはいかがでしょうか。