1. 導入
Javaの歴史において、switch文は「フォールスルー(breakの書き忘れによる意図しない動作)」というバグの温床でした。しかし、Java 14で導入され、Java 17で正式採用された「switch式(Switch Expressions)」と「Arrow syntax(->)」により、この課題は劇的に解消されました。本稿では、現代のJava開発において不可欠なこの構文を、実務的な視点で解説します。
2. 基礎知識
従来のswitch文は「文(Statement)」であり、値を返すことができませんでした。一方、switch式は「式(Expression)」として評価され、結果を変数に代入したり、メソッドの戻り値として直接利用できます。ここで鍵となるのが「Arrow syntax(->)」です。これを用いることで、従来のcaseラベルの後にあったbreakを記述する必要がなくなり、単一の式またはブロックの結果がそのまま戻り値として扱われるようになります。
3. 実装/解決策
Arrow syntaxを用いる場合、以下のルールが適用されます。
・矢印の右側が単一の式であれば、その値が結果となる。
・ブロック({})を使う場合は、yieldキーワードを使って値を返す。
・全網羅性(Exhaustiveness)が求められるため、enumやsealed classで値を判定する場合、デフォルトケースが不要(コンパイラが漏れを検知する)になる。
4. サンプルプログラム
以下は、sealed class(封印クラス)と組み合わせて、安全に型を判定する実用的なコード例です。
public class SwitchExample {
// 継承を制限したsealed classを定義
sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
public double calculateArea(Shape shape) {
// switch式とArrow syntaxの組み合わせ
// break不要で、網羅性が保証される
return switch (shape) {
case Circle c -> Math.PI c.radius() c.radius();
case Rectangle r -> r.width() r.height();
// sealed classにより、全パターンが網羅されているためdefaultは不要
};
}
public static void main(String[] args) {
Shape myShape = new Circle(5.0);
SwitchExample example = new SwitchExample();
System.out.println(“面積: ” + example.calculateArea(myShape));
}
}
5. 応用・注意点
実務で活用する際のポイントを3点挙げます。
1. 網羅性の恩恵: enumやsealed classをswitch式で扱う際、もし将来的に新しいサブクラスが追加された場合、コンパイルエラーとして漏れを検知できます。これにより、仕様変更時の修正漏れを防げます。
2. 副作用の回避: switch式は、副作用(外部の状態変更など)を伴わない関数型プログラミング的なスタイルと非常に相性が良いです。可能な限り、単純な値の返却に留めるのがクリーンコードの秘訣です。
3. 古いコードとの混在: 既存のレガシーなswitch文(breakが必要なもの)と混同しないよう注意してください。Arrow syntaxを使ったswitch式は、常に値を返す必要があるため、単に処理を実行したいだけの場所では従来の文形式と使い分ける判断力が必要です。
最新のJavaバージョンを利用しているのであれば、古いswitch文は極力避け、このArrow syntaxを積極的に活用してバグの少ない堅牢なコードを書きましょう。

コメント