Java 16 转正的 instanceof 模式匹配(if (o instanceof String s))省掉了手动强转这一步,但更值得搞清楚的是那个绑定出来的模式变量,作用域到底能延伸到代码的哪些角落。这篇真实跑几个边界场景验证。
上一篇:线程优先级真实验证
先确认新语法不改变计算语义,只是省略了手动强转这一步。
InstanceofPatternDemo.java // 传统写法 if (o instanceof Circle) { Circle c = (Circle) o; return Math.PI * c.radius() * c.radius(); } // 模式匹配写法 if (o instanceof Circle c) { return Math.PI * c.radius() * c.radius(); }
oldStyleArea(circle) = 12.566370614359172 patternArea(circle) = 12.566370614359172 两者结果真实一致: true
真实结果确认两种写法计算出完全相同的值,证明模式匹配只是在语法层面把"判断类型 + 强制类型转换 + 声明局部变量"这三步合并成了一步,没有引入任何计算语义上的差异。
这是模式匹配最常见的用法:判断类型的同时,在同一个条件表达式里继续用这个变量做进一步判断。
模式变量 str 在 && 右侧真实可用: HELLO WORLD
真实验证了 if (obj instanceof String str && str.length() > 5) 这种写法真实可以正常编译并运行——因为 && 是短路求值,只有左侧的 instanceof 匹配成功、str 真实完成绑定之后,右侧才会真实执行,编译器能确定这个求值顺序,所以允许 str 在右侧被直接使用。
最容易让人意外的一种写法:在"不匹配就提前返回"的分支之后,继续使用这个模式变量。
InstanceofPatternDemo.java static void printIfString(Object o) { if (!(o instanceof String str)) { return; // 不匹配就提前返回 } // str 在这里真实可用 System.out.println(str); }
obj2 不是 String,真实进入这个分支 printIfString 真实在 return 之后的作用域访问到 str: real string
每一行都是真实运行这段代码得到的结果。