Java 17 模式匹配 instanceof 简介说明
下文笔者讲述Java17之instanceof简介说明,如下所示
模式匹配 `instanceof`简介
Java 16中引入了模式匹配 `instanceof` (JEP 394),
并在 Java 17 中成为稳定特性。
它扩展了传统的 `instanceof` 运算符,
使其不仅能进行类型检查,还能同时完成类型转换,并将结果赋给一个新的变量。
instanceof核心用法
古老写法
Object obj = "Hello, World!";
if (obj instanceof String) {
String s = (String) obj; // 额外的类型转换步骤
System.out.println(s.length());
}
模式匹配写法:
Object obj = "Hello, World!";
if (obj instanceof String s) { // 类型检查、转换、赋值一步完成
System.out.println(s.length()); // 在这里可以直接使用变量 s
}
变量作用域
模式变量
(如上例中的`s`)
的作用域仅限于 `if` 语句的布尔表达式为 `true` 的代码块内
这避免变量泄露,使代码更安全
instanceOf适用场景
模式匹配 `instanceof` 在任何需要进行类型检查和转换的地方都能简化代码
让代码更简洁和易读
替代繁琐的类型转换:
这是最直接的用途。
在 `if-else if` 链中处理不同类型
public void process(Object obj) {
if (obj instanceof String s) {
System.out.println("处理字符串: " + s);
} else if (obj instanceof Integer i) {
System.out.println("处理整数: " + i);
} else if (obj instanceof list<?> list) {
System.out.println("处理列表,大小为: " + list.size());
} else {
System.out.println("未知类型");
}
}
密封类 + 模式匹配 `instanceof`:黄金组合
在处理**密封类的子类**时,
可以编写出非常优雅且安全的代码。
场景:处理不同的 `Shape`
假设我们有一个`Shape`密封类层次结构
我们想计算一个 `Shape` 对象的面积。
古老方法
public double calculateArea(Shape shape) {
if (shape instanceof Circle) {
Circle circle = (Circle) shape;
return Math.PI * circle.getRadius() * circle.getRadius();
} else if (shape instanceof Square) {
Square square = (Square) shape;
return square.getSide() * square.getSide();
} else if (shape instanceof Triangle) {
Triangle triangle = (Triangle) shape;
return 0.5 * triangle.getBase() * triangle.getHeight();
} else {
// 理论上,如果 Shape 是密封的且所有子类都被覆盖,这个分支是不可达的
throw new IllegalArgumentException("未知的形状: " + shape);
}
}
借助密封类 + 模式匹配 `instanceof`
public double calculateArea(Shape shape) {
if (shape instanceof Circle c) {
return Math.PI * c.radius() * c.radius(); // 假设使用了 record
} else if (shape instanceof Square s) {
return s.side() * s.side();
} else if (shape instanceof Triangle t) {
return 0.5 * t.base() * t.height();
}
// 注意:这里没有 else 分支!
// 因为 Shape 是密封的,且 permits 了 Circle, Square, Triangle,
// 编译器知道这三个 if-else 分支已经覆盖了所有可能的情况。
// 如果将来向 Shape 的 permits 列表添加了新的子类,编译器会报错,提醒你在这里添加相应的处理逻辑。
}
instanceof优势
1. 代码更简洁:
省去了显式的类型转换
2.可读性更高:
意图更加明确。
3.编译时安全性 (Exhaustiveness Check):
这是最大的优势。
如果 `Shape` 是一个密封类,并且你的 `if-else if` 链覆盖了所有 `permits` 的子类,编译器会认可这一点。
如果你遗漏了某个子类,或者将来 `Shape` 增加了新的子类,
编译器会在编译时就报错,强制你处理所有可能的情况,
从而避免了潜在的运行时错误。
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


