一、枚举类型——新特性(智能转型)

JDK 16 最终完成了 JEP (Java增强建议)394的定稿,但它有个糟糕的名字,即“针对 instanceof 的模式匹配”(Pattern Matching for instanceof)。如果你看到了完整的模式匹配,便会明白这个名字不是很合理。称其为“模式匹配支持”(support for pattern matching)可能会更恰当。在 Kotlin 语言中,该特性被简单地称为“智能转型”(smart casting),因为一旦确定类型后,就永远不需要对其转型了。

下面的示例中可以看到如何分别用旧方法和新方法实现同样的目的:

SmartCasting.java

public class SmartCasting {
    static void dumb(Object x) {
        if (x instanceof String) {
            String s = (String) x;
            if (s.length() > 0) {
                System.out.format("%d %s%n", s.length(), s.toUpperCase());
            }
        }
    }

    static void smart(Object x) {
        if (x instanceof String s && s.length() > 0) {
            System.out.format("%d %s%n", s.length(), s.toUpperCase());
        }
    }

    static void wrong(Object x) {
        // “||”永远不会生效:
        // if(x instanceof String s || s.length() > 0) {}
        // error: cannot find symbol   ^
    }

    public static void main(String[] args) {
        dumb("dumb");
        smart("smart");
    }
}

运行结果如下:

在这里插入图片描述

在 dumb() 中,一旦 instanceof 确定了 x 是 String 后,就必须显式地将它转型为 String s。否则就得在该函数中其余的地方到处插入转型操作。但是在 smart() 中,注意 x instanceof String s 自动用String 类型创建了一个新的变量 s。s 在整个作用域中都可用,即使是在剩余的 if 条件中,如 && s.length() > 0 中所示。这样可以得到更紧凑的代码。

从 wrong() 可以看出,在 if 智能转型表达式中只能使用 &&。使用 || 则意味着可能 x 是个 instanceof String,也可能 s.length() > 0。但这也就意味着 x 也可能不是String,在这种情况下,Java就不会将x 智能转型以生成 s,因此 s 在 || 右侧是不可用的。

JEP 394 将 s 称为模式变量(pattern variable)。

虽然这个特性并未完全消除某些混乱的if语句,但这并不是加入该特性的目的。该特性是作为模式匹配的构建块而引入的,你很快就会看到。

该特性可以产生某些奇怪的作用域行为:

OddScoping.java

public class OddScoping {
    static void f(Object o) {
        if (!(o instanceof String s)) {
            System.out.println("Not a String");
            throw new RuntimeException();
        }
        //此处s仍在作用戏中!
        System.out.println(s.toUpperCase());  // [1]
    }

    public static void main(String[] args) {
        f("Curiouser and Curiouser");
        f(null);
    }
}

[1] 只有在不引入会引发异常的语句时,s 才在作用域中。如果注释掉 throw new RuntimeException(),编译器便会告诉你它无法在行 [1] 中找到 s ——这是你通常所预期的行为。

乍一看这像个 bug,但它就是这么设计的——该行为在 JEP 394 中有着明确的描述。尽管这可以说是一个极端情况,但你能想象追踪由这种行为引起的 bug 会有多么困难。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小熊猫呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值