列挙型を使った switch 式
最新の switch 式と列挙型を使って、漏れのない簡潔な分岐を記述します。
「列挙型を使った switch 式」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
列挙型を使ったswitch式
列挙型を使ったswitch式(Java 14以降)では、型に基づく振り分けを網羅的かつ簡潔に記述できます。すべての列挙型定数を網羅している場合、defaultは必要ありません。
従来のswitch文
従来のswitch文は列挙型で動作しますが、フォールスルーを防ぐにはbreakが必要です。
enum Severity { LOW, MEDIUM, HIGH, CRITICAL }
Severity s = Severity.HIGH;
String action;
switch (s) {
case LOW:
action = "Log and monitor";
break;
case MEDIUM:
action = "Notify on-call team";
break;
case HIGH:
action = "Page engineer immediately";
break;
case CRITICAL:
action = "Activate incident response";
break;
default:
action = "Unknown";
}
System.out.println(action); // Page engineer immediatelyアローラベルを使ったswitch式
アローラベルを使ったswitch式では、フォールスルーとbreakがなくなります。値を評価して返し、網羅性が必要です。
enum Severity { LOW, MEDIUM, HIGH, CRITICAL }
Severity s = Severity.HIGH;
String action = switch (s) {
case LOW -> "Log and monitor";
case MEDIUM -> "Notify on-call team";
case HIGH -> "Page engineer immediately";
case CRITICAL -> "Activate incident response";
// no default needed — all cases covered
};
System.out.println(action); // Page engineer immediatelyブロックを使ったswitch式
caseの処理に複数の文が必要な場合は、yieldを使ったブロックで結果の値を生成します。
enum DayOfWeek { MON, TUE, WED, THU, FRI, SAT, SUN }
DayOfWeek day = DayOfWeek.FRI;
int hoursOpen = switch (day) {
case MON, TUE, WED, THU -> 8;
case FRI -> {
System.out.println("Half day on Friday!");
yield 4; // yield returns value from block
}
case SAT, SUN -> 0;
};
System.out.println("Hours open: " + hoursOpen); // Hours open: 4複数のケースをグループ化する
複数のenum定数を、カンマ区切りで同じcaseにまとめられます。
enum Season { SPRING, SUMMER, FALL, WINTER }
Season season = Season.SUMMER;
String activity = switch (season) {
case SPRING, FALL -> "Hike in the mountains";
case SUMMER -> "Beach vacation";
case WINTER -> "Ski at the resort";
};
System.out.println(activity); // Beach vacationswitchでメソッドから値を返す
switch式はメソッドのreturn文で特に便利で、意図を明確に表現できます。
enum Priority { LOW, NORMAL, HIGH, URGENT }
static int getSlaHours(Priority p) {
return switch (p) {
case LOW -> 72;
case NORMAL -> 24;
case HIGH -> 4;
case URGENT -> 1;
};
}
System.out.println(getSlaHours(Priority.URGENT)); // 1
System.out.println(getSlaHours(Priority.LOW)); // 72ストリーム内のswitch式
ストリーム操作の中でswitch式を使用すると、要素ごとの変換を簡潔に記述できます。
import java.util.*;
import java.util.stream.*;
enum Status { PENDING, ACTIVE, CLOSED }
record Account(String id, Status status) {}
List<Account> accounts = List.of(
new Account("A1", Status.ACTIVE),
new Account("A2", Status.PENDING),
new Account("A3", Status.CLOSED)
);
accounts.stream()
.map(a -> a.id() + ": " + switch (a.status()) {
case ACTIVE -> "\u2705 Live";
case PENDING -> "\u23f3 Awaiting activation";
case CLOSED -> "\u274c Deactivated";
})
.forEach(System.out::println);コンパイル時の網羅性チェック
コンパイラは、すべてのenum定数が網羅されていることを強制します。enumに新しい定数を追加すると、それを処理していないすべてのswitch式でコンパイルエラーが発生します。
enum Color { RED, GREEN, BLUE } // add YELLOW here → compile error below
Color c = Color.GREEN;
// This switch is exhaustive for RED, GREEN, BLUE
// If you add YELLOW to the enum without adding a case here,
// the compiler will report an error.
String hex = switch (c) {
case RED -> "#FF0000";
case GREEN -> "#00FF00";
case BLUE -> "#0000FF";
};
System.out.println(hex); // #00FF00安全性のためのdefault付きswitch
switch文(式ではないもの)を使用する場合、または意図的に一部のケースだけを対象にする場合は、default caseを追加します。
enum Feature { DARK_MODE, PUSH_NOTIFICATIONS, ANALYTICS, BETA_FEATURE }
static boolean isEnabled(Feature feature) {
return switch (feature) {
case DARK_MODE, PUSH_NOTIFICATIONS -> true;
case ANALYTICS -> false;
default -> {
System.out.println("Unknown feature: " + feature);
yield false;
}
};
}
System.out.println(isEnabled(Feature.DARK_MODE)); // true
System.out.println(isEnabled(Feature.BETA_FEATURE)); // false実践:注文のライフサイクル
switch式を使用して許可される遷移を判定する、注文のライフサイクル全体を表す状態機械です。
enum OrderState { CART, PENDING, CONFIRMED, SHIPPED, DELIVERED, CANCELLED }
static Set<OrderState> allowedTransitions(OrderState from) {
return switch (from) {
case CART -> Set.of(OrderState.PENDING, OrderState.CANCELLED);
case PENDING -> Set.of(OrderState.CONFIRMED, OrderState.CANCELLED);
case CONFIRMED -> Set.of(OrderState.SHIPPED);
case SHIPPED -> Set.of(OrderState.DELIVERED);
case DELIVERED, CANCELLED -> Set.of(); // terminal states
};
}
System.out.println(allowedTransitions(OrderState.PENDING));
// [CONFIRMED, CANCELLED]Stringとenumのswitchの比較
Stringでswitchを使用する場合はnullチェックが必要で、大文字と小文字を区別します。enumでのswitchはnullを許容せず(nullの場合はNPEになり)、型安全です。値の集合が既知の場合はenumを優先してください。
// String switch — fragile
String role = "admin";
String label = switch (role.toLowerCase()) {
case "admin" -> "Administrator";
case "guest" -> "Guest User";
default -> "Unknown";
};
// Enum switch — type-safe
enum Role { ADMIN, GUEST }
Role r = Role.ADMIN;
String label2 = switch (r) {
case ADMIN -> "Administrator";
case GUEST -> "Guest User";
};
System.out.println(label2); // Administratorクイックチェック
4つの定数を持つenumがあり、4つすべてを対象とするswitch式を書いたとします。そのenumに5つ目の定数を追加すると、どうなりますか。
復習:enumを使ったswitch式
重要なポイント:
- 矢印ラベルのswitch式では、breakとフォールスルーが不要になります
- ブロック形式のcaseから値を返すにはyieldを使用します
- 複数の定数はカンマでまとめます:case A, B ->
- すべての定数を網羅するswitch式では、defaultは不要です
- 新しいenum定数を追加すると、網羅的なswitch式でコンパイルエラーが発生します
- switch式はストリームのmap()操作で特に便利です
よくある質問
「列挙型を使った switch 式」レッスンは無料ですか?
はい。「列挙型を使った switch 式」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「列挙型を使った switch 式」で何を学びますか?
最新の switch 式と列挙型を使って、漏れのない簡潔な分岐を記述します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「列挙型を使った switch 式」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 列挙型の定義と使用
- フィールドとメソッドを持つ列挙型
- 列挙型を使った switch 式
- EnumSet と EnumMap