1. 導入:なぜ今、switch式なのか
従来のswitch文は、breakの書き忘れによるフォールスルー(意図しないケースへの連鎖)や、冗長なコード記述がバグの温床となってきました。Java 14で正式導入された「switch式」は、これらの課題を解消し、値を直接返す「式」として利用することで、コードをより宣言的で安全なものに変えてくれます。現代のJava開発において、可読性と保守性を高めるために必須のテクニックです。
2. 基礎知識:switch文とswitch式の違い
従来の「文(Statement)」は、処理を実行するだけで値を返しませんでした。一方、新しくなった「式(Expression)」は、処理結果を直接変数に代入したり、メソッドの戻り値として使用したりできます。
ここで重要なのが「アロー演算子(->)」です。これを使うことで、breakを書く必要がなくなり、コードが圧倒的にスッキリします。また、網羅性チェック(Exhaustiveness)が働くため、すべてのケースをカバーしていない場合にコンパイルエラーとなり、バグを未然に防げるのが大きなメリットです。
3. 実装と解決策:アロー演算子とyieldの活用
switch式では、値を返すために「->」を使用します。もし、ブロック内で複雑な処理をしてから値を返したい場合は「yield」キーワードを使用します。
また、Sealed Classes(封印クラス)と組み合わせることで、特定の型のみを許容する厳密なパターンマッチングが可能になります。これにより、将来的な拡張時に「新しい型を追加したのにswitch側で処理し忘れる」というミスをコンパイル時に検知できるようになります。
4. サンプルプログラム
以下のコードは、列挙型とswitch式を組み合わせ、給与計算を行う実用的な例です。
public class SwitchExpressionExample {
public enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
public static void main(String[] args) {
Day today = Day.MON;
// switch式を使って値を直接変数に代入
int workingHours = switch (today) {
case MON, TUE, WED, THU, FRI -> 8; // アロー演算子で値を返す
case SAT, SUN -> 0;
// 全ケースを網羅しているため、defaultは不要
};
System.out.println("今日の勤務時間: " + workingHours + "時間");
// 複雑な処理が必要な場合はyieldを使用
String message = switch (today) {
case MON -> {
System.out.println("週の始まりです。");
yield "頑張りましょう"; // ブロック内で値を返す場合はyield
}
case FRI -> "あと少し!";
default -> "休日です";
};
System.out.println(message);
}
}
5. 応用・注意点:現場で役立つTIPS
網羅性の担保:
switch式はすべての可能性をカバーする必要があります。enumであれば全定数を記述すればOKですが、intやStringの場合は必ず「default」句が必要です。もし将来的にenumに値が増える可能性があるなら、あえてdefaultを書かずにコンパイラの警告を頼りにするのも、堅牢なコードを保つ戦略です。
if-elseとの使い分け:
条件が単純な真偽値の分岐であればif-elseが適していますが、3つ以上の状態や、型の判別(パターンマッチング)が絡む場合は、積極的にswitch式へ移行してください。特にSealed Classesと組み合わせることで、ドメインモデルの整合性を強力に保護できます。
最後に、既存コードのリファクタリングを行う際は、まず「breakの多い古いswitch文」をターゲットにしてみてください。それだけでコードの行数が減り、バグの発生率を大幅に下げることができます。

コメント