184. Java 模式匹配 - `instanceof` 模式匹配详解

104 阅读2分钟

184. Java 模式匹配 - instanceof 模式匹配详解

Java 16 开始,instanceof 引入了“模式匹配Pattern Matching)”的能力,使得代码更简洁、可读性更高。

🧠 什么是 instanceof 模式匹配?

我们以前使用 instanceof 判断类型时,往往还要显式地进行类型转换(cast)。而从 Java 16 开始,我们可以在 instanceof 判断的同时,声明一个变量用于接收匹配后的结果


✅ 基本用法示例

public void print(Object o) {
    if (o instanceof String s) {
        System.out.println("This is a String of length " + s.length());
    } else {
        System.out.println("This is not a String");
    }
}

🧩 背后的三个组成部分

要素含义示例
匹配目标(Target要进行判断的对象o
模式(Pattern判断的类型 + 变量名String s
匹配结果(Result模式变量(Pattern Variables,类型为 String,只在匹配成功时创建

🔄 模式变量的范围

模式变量(如 s)的作用域限定在判断成功的逻辑分支内。你可以在 if 的代码块中使用,也可以在布尔表达式中进行进一步判断。


🎯 示例:匹配字符串且不为空

public void print(Object o) {
    if (o instanceof String s && !s.isEmpty()) {
        System.out.println("Non-empty String of length " + s.length());
    } else {
        System.out.println("Not a non-empty String.");
    }
}

💡 只有在 o instanceof String s 为真时,才会创建变量 s,因此 !s.isEmpty() 是安全的。


🧹 Java 16 前的写法 vs Java 16 后的改进

🧾 Java 16 前:

public void print(Object o) {
    if (!(o instanceof String)) {
        return;
    }
    String s = (String) o;
    System.out.println("This is a String of length " + s.length());
}

🚀 Java 16 模式匹配写法:

public void print(Object o) {
    if (!(o instanceof String s)) {
        return;
    }
    System.out.println("This is a String of length " + s.length());
}

✅ 更简洁、类型转换由编译器自动完成,代码更安全、清晰。


💥 编译器智能分析

有些判断永远不会成立,编译器能直接报错:

Double pi = Math.PI;
if (pi instanceof String s) {
    // ❌ 编译错误:Double 永远不可能是 String 的实例
}

因为 Stringfinal 类,不能被继承,因此不可能出现 DoubleString 的情况。


🏗️ 更优雅的 equals() 写法示例

下面是经典的 equals 方法(传统写法):

public class Point {
    private int x;
    private int y;

    public boolean equals(Object o) {
        if (!(o instanceof Point)) {
            return false;
        }
        Point point = (Point) o;
        return x == point.x && y == point.y;
    }
}

✨ 使用模式匹配后的重写版本:

@Override
public boolean equals(Object o) {
    return o instanceof Point point &&
           x == point.x &&
           y == point.y;
}

👌 优点:去掉了冗余的类型转换(cast),代码更短更清晰!


📌 小结

特性说明
✅ 自动类型转换匹配成功后,自动为你声明并转换变量
✅ 安全简洁减少强制类型转换,避免 ClassCastException
✅ 条件控制更灵活可与 &&
✅ 可读性提升大幅减少冗余代码,逻辑清晰

🧠 附加:类型兼容性说明

你可以使用 instanceof 模式匹配 类、抽象类、接口,例如:

if (o instanceof CharSequence cs) {
    System.out.println("Length: " + cs.length());
}

因为 String 实现了 CharSequence,因此匹配成功。