この記事の要点
• switch文は値をラベルと比較して分岐する伝統的な構文
• switch式(Java 14+)は矢印(->)で値を返せる新形式
• switch式は break 不要で、yield で値を返せる
このシリーズについて
「Java入門」は1本1テーマで進む全15回のシリーズです。本記事はその第7回として、switch文とswitch式を解説します。
前提条件: Java入門 #1 - 開発環境構築 でJDK 21 がインストール済み。if文の基礎を理解済み。
switchとは
switch は、1つの変数や式の値を複数のラベル(case)と比較して分岐する構文です。if-else if の連鎖よりも読みやすくなることが多いです。
if (day.equals("月")) {
System.out.println("Monday");
} else if (day.equals("火")) {
System.out.println("Tuesday");
} else if (day.equals("水")) {
System.out.println("Wednesday");
}
// ... 長い
これを switch で書くと以下のようになります。
switch (day) {
case "月" -> System.out.println("Monday");
case "火" -> System.out.println("Tuesday");
case "水" -> System.out.println("Wednesday");
}
旧来のswitch文(case + break)
Java 13以前から存在する伝統的な構文です。各 case の末尾に break を書かないと、次の case に処理が流れ込みます(フォールスルー)。
// Java 21(旧形式も動作する)
public class OldSwitch {
public static void main(String[] args) {
int day = 3;
String dayName;
switch (day) {
case 1:
dayName = "月曜日";
break;
case 2:
dayName = "火曜日";
break;
case 3:
dayName = "水曜日";
break;
default:
dayName = "不明";
break;
}
System.out.println(dayName); // "水曜日"
}
}
注意: break を書き忘れると意図しない動作になります。旧形式を使う場合は注意が必要です。
フォールスルーの例
int month = 3;
switch (month) {
case 12:
case 1:
case 2:
System.out.println("冬");
break;
case 3:
case 4:
case 5:
System.out.println("春");
break;
default:
System.out.println("他の季節");
}
// 出力: 春
複数の case ラベルを続けて書くことで、同じ処理をまとめることができます。
switch式(Java 14で正式化)
Java 14 で正式に導入されたswitch式は、以下の特徴を持ちます。
- 矢印構文(
->) でフォールスルーを防ぐ - 値を返せる(式として使える)
breakが不要- 複数文が必要なら
{}ブロックで囲み、yieldで値を返す
基本構文
変数 = switch (式) {
case ラベル1 -> 値1;
case ラベル2 -> 値2;
default -> デフォルト値;
};
実例を見ましょう。
// Java 21
public class NewSwitch {
public static void main(String[] args) {
int day = 3;
String dayName = switch (day) {
case 1 -> "月曜日";
case 2 -> "火曜日";
case 3 -> "水曜日";
case 4 -> "木曜日";
case 5 -> "金曜日";
default -> "週末または不明";
};
System.out.println(dayName); // "水曜日"
}
}
ポイント: switch式は値を返すため、変数に直接代入できます。旧形式のように途中で break を書く必要がありません。
複数ラベルのマッチ
カンマで区切って複数のラベルを1つの case にまとめられます。
// Java 21
String season = switch (month) {
case 12, 1, 2 -> "冬";
case 3, 4, 5 -> "春";
case 6, 7, 8 -> "夏";
case 9, 10, 11 -> "秋";
default -> "不明";
};
System.out.println(season);
yieldで値を返す
複数の文を実行してから値を返したい場合は、{} ブロックで囲み、yield キーワードで値を返します。
// Java 21
public class SwitchWithYield {
public static void main(String[] args) {
int score = 85;
String grade = switch (score / 10) {
case 10, 9 -> "A";
case 8 -> {
System.out.println("良い成績です");
yield "B";
}
case 7 -> "C";
default -> {
System.out.println("もう少し頑張りましょう");
yield "D";
}
};
System.out.println("評価: " + grade);
}
}
// 出力:
// 良い成績です
// 評価: B
補足: yield は switch式の中でのみ使います。通常の return とは異なり、switch式の結果として値を返すだけで、メソッドから抜けるわけではありません。
旧switch文 vs switch式の比較
| 項目 | 旧switch文 | switch式(Java 14+) |
|---|---|---|
| 構文 | case ラベル: | case ラベル -> |
| フォールスルー | あり(break 必須) | なし |
| 値を返す | 不可(変数に代入する必要) | 可(式として使える) |
| 複数ラベル | 縦に並べる | カンマ区切り |
| 複数文の実行 | そのまま書く | {} + yield |
| 推奨度 | △(互換性のため残る) | ★★★(Java 14以降は推奨) |
実例:コマンド処理
実際のプログラムで switch式 を使った例を見てみましょう。
// Java 21
import java.util.Scanner;
public class CommandProcessor {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("コマンドを入力 (start/stop/status/help): ");
String command = scanner.nextLine().trim().toLowerCase();
String result = switch (command) {
case "start" -> "サービスを開始しました";
case "stop" -> "サービスを停止しました";
case "status" -> "サービスは実行中です";
case "help" -> {
System.out.println("利用可能なコマンド:");
System.out.println(" start - サービス開始");
System.out.println(" stop - サービス停止");
System.out.println(" status - 状態確認");
yield "ヘルプを表示しました";
}
default -> "不明なコマンド: " + command;
};
System.out.println(result);
scanner.close();
}
}
このコードは以下を実現しています。
- 複数の固定値を簡潔に判定
helpコマンドでは{}とyieldで複数行処理defaultで想定外の入力をハンドリング
switchで使える型
Java 21 では以下の型を switch で使えます。
| 型 | 例 |
|---|---|
byte, short, int | switch (num) |
char | switch (ch) |
String | switch (text) |
enum 型 | switch (dayOfWeek) |
| パターンマッチング(Java 21+) | switch (obj) ※型でマッチ |
補足: Java 21 ではパターンマッチングが正式化され、switch で型による分岐も可能になりました(詳細は別記事で扱います)。
よくあるミス
| ミス | 説明 | 対策 |
|---|---|---|
旧形式で break 忘れ | 次の case に流れ込む | switch式(矢印構文)を使う |
default を書かない | 網羅していない値でエラー | 必ず default を追加 |
式の中で return を使う | コンパイルエラー | yield を使う |
複数文を yield なしで書く | エラー | {} + yield で囲む |
次のステップ
Java入門 #8 - for文(繰り返し) で、同じ処理を繰り返し実行する方法を学びます。
参考リソース
- JEP 361: Switch Expressions — Java 14で正式化されたswitch式の仕様
- Oracle Java SE 21 - Switch Expressions — 公式ドキュメント
- The Java Tutorials - The switch Statement — Oracle公式チュートリアル