0Pricing
Java Academy · レッスン

列挙型を使った 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 vacation

switchでメソッドから値を返す

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 列挙型の定義と使用
  2. フィールドとメソッドを持つ列挙型
  3. 列挙型を使った switch 式
  4. EnumSet と EnumMap
← Java Academyに戻る