Java 21正式引入switch模式匹配(JEP 441),支持类型检查+变量绑定、null显式处理、穷尽性校验,结合sealed class与record可实现安全简洁的多条件分支。

Java 14 引入了 Pattern Matching(模式匹配)的预览特性,但真正支持多条件分支优化的是从 Java 16 开始的 instanceof 模式匹配,以及 Java 21 正式发布的 switch 模式匹配(JEP 441)。它让原本冗长、嵌套、易出错的多条件类型判断和值判断代码变得更简洁、安全、可读性更强。
用 switch 模式匹配替代 if-else 链判断对象类型
传统方式需多次 instanceof + 强制转换,容易漏判、空指针或类型不安全:
if (obj instanceof String s) {
return s.length();
} else if (obj instanceof Integer i) {
return i.toString().length();
} else if (obj instanceof List<?> list) {
return list.size();
} else {
return -1;
}
用 Java 21+ 的 switch 模式匹配可写成:
return switch (obj) {
case String s -> s.length();
case Integer i -> i.toString().length();
case List<?> list -> list.size();
case null -> -1; // 显式处理 null(推荐)
default -> -1;
};
- 每个 case 自动完成类型检查 + 变量绑定(如
String s),无需手动 cast -
null可作为独立 case 处理,避免 NPE 或漏判 - 编译器保证穷尽性(若类型是 sealed class,且所有子类都被覆盖,default 可省略)
- 表达式形式天然支持返回值,无 break 穿透风险
结合 record 和 sealed class 实现更安全的多条件分支
当你的数据结构是明确、有限的几种形态时(比如解析不同类型的 JSON 值、AST 节点、消息体),配合 sealed class + record + switch 模式匹配 效果最佳:
立即学习“Java免费学习笔记(深入)”;
sealed interface Expr permits Constant, Add, Multiply {}
record Constant(int value) implements Expr {}
record Add(Expr left, Expr right) implements Expr {}
record Multiply(Expr left, Expr right) implements Expr {}
计算逻辑可直接 switch:
int eval(Expr e) {
return switch (e) {
case Constant(int v) -> v;
case Add(Expr l, Expr r) -> eval(l) + eval(r);
case Multiply(Expr l, Expr r) -> eval(l) * eval(r);
}; // sealed 接口已穷尽,无需 default
}
- 编译器强制你覆盖所有子类型,漏写会报错,杜绝运行时逻辑遗漏
- record 字段自动解构,语义清晰,无需 getter 或临时变量
- 递归调用自然简洁,无样板代码
用类型模式 + 常量模式组合做复合条件判断
Pattern Matching 不限于单一层级。你可以在 case 中嵌套常量、guard(守卫条件)、甚至其他模式:
return switch (obj) {
case String s && s.length() > 10 -> "long string";
case String s -> "short string";
case Integer i when i > 100 -> "big int";
case Integer i -> "small int";
case List<?> list when list.isEmpty() -> "empty list";
case List<?> list -> "non-empty list";
default -> "unknown";
};
-
&&连接类型模式与布尔表达式(仅限 Java 21+) -
when后跟 guard 表达式,用于进一步过滤(比 if 内嵌更声明式) - 多个 case 可按优先级顺序排列,逻辑分层更直观
注意事项和迁移建议
- 确保项目使用 JDK 21+,并启用 --enable-preview(若用早期版本预览特性);正式版(JDK 21+)无需 preview 参数
- switch 模式匹配只适用于引用类型(包括 null)、record、sealed 类型;基本类型仍用传统 switch
- 避免在 guard 中写副作用代码(如修改状态、IO),因执行时机不保证
- 旧代码迁移时,先从高频率、多分支、易出错的 instanceof/if 链入手,收益最明显


















