CodeGym /课程 /JAVA 25 SELF /高级 switch-表达式

高级 switch-表达式

JAVA 25 SELF
第 10 级 , 课程 5
可用

1. switch 有哪些新变化

如果你在 Java 14 之前写过代码,switch 大致如下:

switch (day) 
{
    case MONDAY:
        System.out.println("新的一周开始!");
        break;
    case FRIDAY:
        System.out.println("周五,耶!");
        break;
    default:
        System.out.println("平常的一天。");
        break;
}

看起来没什么问题,但有这些麻烦:

  • 必须记得写 break(否则会“落入”下一个 case)。
  • 重复代码很多。
  • 如果想返回值,就得事先声明一个变量,并在每个 case 内给它赋值。

Java 14+ 说:够了!该让 switch 更方便、更现代了。

主要改进:

  • Switch 变成了表达式,不仅仅是语句——现在它可以返回值。
  • 使用箭头 -> 的新语法,替代冒号和 break
  • 多个 case 可以用逗号合并——用于相同逻辑。
  • 编译器会检查所有分支是否被处理(尤其是 enum)。
  • 不再有“贯穿”(fall-through)的风险——只有显式才可能发生。

2. switch 表达式的语法


switch (znachenie)
{
   case A, B -> rezultat1;
   case C -> {
      // 几个操作
      yield rezultat2;
   }
   default -> rezultatPoUmolchaniyu;
}
->yield 的 switch 表达式语法

基本示例

直入主题:现在可以这样从 switch 返回值:

DayOfWeek day = DayOfWeek.MONDAY;

String message = switch (day) 
{
    case MONDAY, FRIDAY, SUNDAY -> "短周或休息日!";
    case TUESDAY                -> "星期二——艰难的一天。";
    case WEDNESDAY, THURSDAY    -> "周中!";
    case SATURDAY               -> "耶,星期六!";
    // 如果不是所有分支都覆盖,必须有 default
    default                     -> "有点奇怪的一天...";
};

System.out.println(message);

这里发生了什么:

  • switch (day) 是一个会返回值的表达式。
  • 箭头 -> 之后就是该 case 的结果。
  • 多个 case 可以用逗号合并。
  • 完全不需要 break——Java 自己知道分支在哪里结束。
  • 可以直接把结果赋给变量 message

数字示例

int code = 404;
String result = switch (code) 
{
    case 200 -> "OK";
    case 400, 404 -> "客户端错误";
    case 500 -> "服务器错误";
    default -> "未知代码";
};
System.out.println(result);

字符串示例

String command = "start";
String status = switch (command) 
{
    case "start" -> "启动!";
    case "stop" -> "停止!";
    case "pause" -> "暂停...";
    default -> "未知命令";
};
System.out.println(status);

配合 yield 的代码块

有时需要在一个 case 中执行多步操作(例如进行复杂计算或记录日志)。此时可以使用 { ... } 代码块并配合关键字 yield

int n = 7;
String parity = switch (n % 2) 
{
    case 0 -> "偶数";
    case 1 -> 
    {
        System.out.println("检测到奇数: " + n);
        yield "奇数";
    }
    default -> "有点奇怪";
};
System.out.println(parity);

重要:在代码块里必须写 yield,它为该 case 返回值。

3. 新语法的优势

无需写 break

在经典的 switch 中,忘记写 break 往往带来痛苦和神秘的 bug。在新语法里 break 完全不需要:每个分支都会自动结束。

编译器检查所有分支是否覆盖

如果你使用 enum 而没有处理所有值——没有 default 的情况下,编译器将不允许通过构建。这让代码更可靠。

没有“贯穿”(fall-through)

在经典的 switch 中,如果忘了 break,执行会“贯穿”到下一个 case。在新语法中这不可能(除非你使用语句块并显式写 break——但这里并不需要它)。

代码更简洁、更易读

自己对比一下:

之前:

String result;
switch (status) {
    case "OK":
        result = "一切都好";
        break;
    case "ERROR":
        result = "错误";
        break;
    default:
        result = "未知";
        break;
}

之后:

String result = switch (status) {
    case "OK" -> "一切都好";
    case "ERROR" -> "错误";
    default -> "未知";
};

多个 case——一套逻辑

case MONDAY, FRIDAY, SUNDAY -> "休息日或短的一天!";

4. 与经典 switch 的对比

特性 经典 switch 新版 switch
必须写 break
贯穿(fall-through)
可返回值 否(只能借助变量) 是(表达式)
多个 case 用逗号
检查所有分支 是(对 enum 尤其严格)
简洁性 代码冗长 简洁明了
可用于 enum 与字符串

5. 与 enum 与字符串的兼容性

enum 示例

假设我们有一个枚举:

enum DayOfWeek 
{
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

在新的 switch 中使用它:

DayOfWeek today = DayOfWeek.WEDNESDAY;

String mood = switch (today) 
{
    case MONDAY -> "起床真难...";
    case FRIDAY -> "快到周末了!";
    case SATURDAY, SUNDAY -> "耶,休息!";
    default -> "工作日。";
};
System.out.println(mood);

配合 String 的示例

String season = "summer";
String activity = switch (season) 
{
    case "winter" -> "滑冰";
    case "summer" -> "在湖里游泳";
    case "autumn" -> "采蘑菇";
    case "spring" -> "听鸟鸣";
    default -> "未知的季节";
};
System.out.println(activity);

6. 将旧 switch 重写为新风格

旧写法:

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);

新写法:

int day = 3;
String dayName = switch (day) 
{
    case 1 -> "星期一";
    case 2 -> "星期二";
    case 3 -> "星期三";
    default -> "未知的日子";
};
System.out.println(dayName);

再举一例:多个 case——一套逻辑

int score = 5;
String grade = switch (score) 
{
    case 5, 6, 7 -> "良好";
    case 8, 9, 10 -> "优秀";
    default -> "需要加把劲";
};
System.out.println(grade);

7. 常见错误和注意事项

错误 1:未覆盖所有分支时缺少 default 如果你对可能出现列举之外值的类型(例如 intString)使用 switch 表达式,编译器会要求提供 default。对于 enum,如果没有处理所有值,default 也必须提供。

错误 2:在块中忘记写 yield 如果在 case 中使用花括号(需要执行多步操作),别忘了 yield——没有它编译器会报错: "Missing yield statement"

错误 3:返回类型不一致。 switch 表达式的所有分支必须返回相同类型的值;否则编译器不会放行代码。

错误 4:case 值重复。 同一个 case 不能写两次——编译器会直接提示错误。

1
调查/小测验
常量、enum 和 switch第 10 级,课程 5
不可用
常量、enum 和 switch
常量、enum 和 switch
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION