java 16 的 instanceof 模式匹配将类型检查与变量抽取合二为一,避免传统写法中重复判断和手动强转的冗余与安全隐患;变量作用域限于对应分支,仅支持引用类型,不支持基本类型或具体泛型参数。

Java 16 引入了 instanceof 的模式匹配(JEP 394),它让类型检查和变量抽取一步完成,彻底避免了传统写法中冗余的强制转换和重复的类型判断,代码更简洁、安全、可读性更高。
传统写法的问题在哪?
在 Java 16 之前,要安全地做类型转换,通常得这样写:
```java
if (obj instanceof String) {
String s = (String) obj; // 必须手动强转
System.out.println(s.length());
}
问题很明显:类型检查(instanceof)和转换((String))是两步,不仅啰嗦,还容易出错——比如检查的是 String,却误转成 Integer;或者漏掉括号导致编译失败。
用模式匹配一步搞定
Java 16+ 允许在 instanceof 后直接声明带类型的模式变量,条件为真时自动绑定并具有该类型:
```java
if (obj instanceof String s) { // ✅ 类型检查 + 变量声明 + 初始化,一气呵成
System.out.println(s.length()); // s 直接是 String 类型,无需强转
}
此时 s 是一个**有效范围限定在 if 块内**的局部变量,编译器已确认其非 null 且为 String 类型,完全类型安全。
在 switch 表达式中结合使用(Java 17+)
Java 17 进一步扩展了模式匹配,支持在 switch 中对对象做多类型分发:
```java
int length = switch (obj) {
case String s -> s.length();
case List> list -> list.size();
case Integer i when i > 100 -> i.toString().length();
case null -> 0;
default -> -1;
};
- 每个
case后的变量(如s、list)都是对应类型的模式变量 -
when子句支持额外布尔条件,增强表达力 -
null可显式匹配,避免 NPE 风险
注意事项和边界情况
模式匹配不是万能的,需注意几点:
- 模式变量的作用域严格受限:只在对应
if分支或case块内有效,出了作用域就不可访问 - 不支持基本类型(如
int、boolean),只能用于引用类型及其包装类(Integer、Boolean等) - 不能用于泛型类型擦除后的原始类型,例如
instanceof List<string> list</string>❌(语法错误),只能写instanceof List> list✅ - 与传统的
isAssignableFrom或反射无关,纯编译期静态检查 + 运行期类型验证
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











