Java 14引入instanceof模式匹配,Java 16转正,支持类型检查与变量绑定一步完成;Java 17扩展至switch表达式,提升多类型处理简洁性、安全性与可读性。

Java 14 引入了 instanceof 模式匹配(JEP 305),并在 Java 16 中正式成为标准特性。它让类型检查和强制转换一步完成,避免冗余的显式转换,代码更简洁、安全、可读性更高。
直接声明并绑定变量(最常用)
传统写法需要先用 instanceof 判断,再手动强转:
if (obj instanceof String) {
String s = (String) obj; // 多写一次类型和变量名
System.out.println(s.length());
}
模式匹配写法直接在 instanceof 后声明带类型的变量,匹配成功时自动绑定:
if (obj instanceof String s) { // 一行搞定判断 + 转换 + 命名
System.out.println(s.length()); // s 已是 String 类型,无需再转
}
- 变量
s的作用域仅限于if块内,编译器保证其非 null 且类型安全 - 若
obj为null,instanceof返回false,s不会被初始化,不会触发 NPE - 不能重复使用已有变量名(如
if (obj instanceof String obj)编译报错)
配合 switch 表达式使用(Java 17+)
Java 17 支持在 switch 中使用类型模式,进一步简化多类型分支处理:
立即学习“Java免费学习笔记(深入)”;
return switch (obj) {
case String s -> "String: " + s.length();
case Integer i -> "Integer: " + i;
case List<?> l -> "List size: " + l.size();
case null -> "Got null";
default -> "Unknown type";
};
- 每个
case后的变量(如s、i)自动完成类型检查与转换 -
null可作为显式 case 处理,避免空指针风险 - 编译器会检查是否覆盖所有可能类型(对 sealed 类尤其有用)
注意边界情况和限制
模式匹配不是万能的,需留意以下几点:
- 只支持引用类型,不支持基本类型(如
instanceof int x无效) - 变量名不能与外层同名,否则编译失败;但可与不同作用域中的同名变量共存
- 不能用于泛型类型擦除后的原始类型判断(如
instanceof List<String> list实际只校验List,泛型信息在运行时不存在) - 在逻辑运算符中要小心优先级:例如
if (obj instanceof String s && s.length() > 0)是合法的,但obj instanceof String s || otherCheck()会导致编译错误(模式变量不能出现在||右侧)
替代传统工厂或 visitor 的轻量场景
对于简单类型分发逻辑(比如解析不同 JSON 结构、处理异构集合),模式匹配比写一堆 if-else 或引入 Visitor 模式更直接:
public String describe(Object data) {
return switch (data) {
case String s -> "text: " + s;
case Integer i when i < 0 -> "negative number";
case Integer i -> "positive number: " + i;
case Map<?, ?> m -> "map with " + m.size() + " entries";
default -> "unknown";
};
}
-
when子句支持额外条件判断,增强表达力 - 所有分支返回相同类型,天然适合函数式风格
- 相比反射或
getClass().getName()字符串匹配,类型安全且性能更好


















