0Pricing
Java Academy · 课时

使用枚举的 switch 表达式

使用现代 switch 表达式处理枚举,实现清晰且覆盖完整的分支逻辑

使用枚举的 switch 表达式 是 CoddyKit 上的免费 Java Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 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 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);

编译时的穷尽性检查

编译器会强制要求覆盖所有枚举常量。向枚举中添加新常量后,所有未处理该常量的 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

使用默认分支确保安全

使用 switch 语句而非表达式时,或者有意只覆盖部分分支时,请添加默认分支。

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 与枚举的 switch 对比

对 String 使用 switch 时,需要进行空值检查,并且区分大小写。对枚举使用 switch 时可以安全处理空值(值为 null 时会产生 NPE),并且具有类型安全性——当值集合已知时,优先使用枚举。

// 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 个常量的枚举,并编写了覆盖全部 4 个常量的 switch 表达式。如果向该枚举中添加第 5 个常量,会发生什么?

回顾:使用枚举的 switch 表达式

要点:

  • 带箭头标签的 switch 表达式无需使用 break,也不会发生贯穿
  • 使用 yield 从块分支中返回值
  • 使用逗号将多个常量分组:case A, B ->
  • 覆盖所有常量的穷尽式 switch 表达式不需要默认分支
  • 添加新的枚举常量会使穷尽式 switch 表达式产生编译错误
  • switch 表达式非常适合用于流的 map() 操作

常见问题解答

「使用枚举的 switch 表达式」课时是免费的吗?

是的 — 「使用枚举的 switch 表达式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。

「使用枚举的 switch 表达式」这节课中我会学到什么?

使用现代 switch 表达式处理枚举,实现清晰且覆盖完整的分支逻辑 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 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