1. 背景问题

在 Java 中,类型判断一直是一个常见操作。最传统的写法是:

if (obj instanceof String) {
    String s = (String) obj;  // 必须强制类型转换
    System.out.println(s.toUpperCase());
}

这种写法的问题在于:

  1. 冗余:必须重复声明 String 类型,并且强转。
  2. 可读性差:逻辑简单,但代码显得啰嗦。

Java 长期以来被诟病“模板代码多”,而 instanceof 的用法就是典型例子。


2. Pattern Matching 的改进

Java 16(预览) 开始,instanceof 引入了 模式匹配(Pattern Matching),在 Java 17 中成为正式特性。

改进后的写法:

if (obj instanceof String s) {
    System.out.println(s.toUpperCase());
}

优点:

  • 省去强制类型转换:直接在 instanceof 表达式里完成匹配和绑定。
  • 作用域更清晰:变量 s 只在 if 块中有效,避免污染外部作用域。
  • 更接近自然语言:读起来像“如果 obj 是 String 类型,就把它叫做 s”。

3. 高级用法

3.1 与逻辑运算符结合

if (obj instanceof String s && s.length() > 5) {
    System.out.println("长字符串: " + s);
}

👉 这里 s 不仅是类型匹配后的变量,还能继续作为布尔表达式的一部分。

3.2 switch 中的模式匹配(结合 JDK 21 的增强版 switch)

static void printType(Object obj) {
    switch (obj) {
        case String s -> System.out.println("字符串:" + s.toUpperCase());
        case Integer i -> System.out.println("整数:" + (i * i));
        case null -> System.out.println("null 值");
        default -> System.out.println("其他类型:" + obj);
    }
}

👉 结合 switch 的模式匹配,让代码比传统 if-else 链条更简洁优雅。

3.3 与 sealed classes 搭配

如果某个父类是 sealed classswitch 可以确保穷尽所有子类,类型安全更强:

sealed interface Shape permits Circle, Rectangle {}

record Circle(double radius) implements Shape {}
record Rectangle(double w, double h) implements Shape {}

static double area(Shape shape) {
    return switch (shape) {
        case Circle c -> Math.PI * c.radius() * c.radius();
        case Rectangle r -> r.w() * r.h();
    };
}

👉 编译器会强制校验是否覆盖了所有子类,减少遗漏。


4. 实战场景

  • 对象解析:比如解析 JSON 节点时,不同类型走不同逻辑。
  • 多态替代方案:在一些场景下,instanceof + 模式匹配 可以替代传统的多态方法调用。
  • 配合 switch:写数据处理、解析器、状态机时,能大幅减少样板代码。

5. 总结

Pattern Matching for instanceof 是 Java 近年来非常实用的语法糖之一,它:

  • 消除了冗余的强制类型转换
  • 让代码可读性更高
  • switchsealed classes 等新特性配合威力更大

一句话总结:从“啰嗦的 instanceof + 强转”到“简洁优雅的模式匹配”,Java 的代码终于变得更现代了。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐