0%

Java语言新特性漫谈:Java 16篇

instanceof操作符的模式匹配(正式版)

该特性在 Java 14 中引入,Java 15 继续作为预览特性,直到 Java 16 才终于成为正式版。

Java 15 没有对该特性做任何修改,Java 16 基本上也没有修改——仅有一点,对于模式变量(pattern variable)不再是隐式 final 的,即可重新赋值。

Java 14 及 Java 15 更新说明文档都没有提及模式变量是隐式 final 的,但实验证实的确是。
这点仅在 Java 16 更新列表中有变更说明。
更多说明可参考《Java语言新特性漫谈:Java 14篇》相关章节。

记录类(正式版)

记录是充当不可变数据的透明载体的类。

该特性在 Java 14 中引入,Java 15 继续作为预览特性,直到 Java 16 才终于成为正式版。

Java 15 使得记录可以声明为局部类,不过,局部记录类是隐式 static 的。

Java 16 中使得普通局部类也可以显式声明为 static 的。这样做的一个好处是,局部记录类可以很容易地转换为“普通局部类”。

密封类(预览特性第2版)

该特性在 Java 15 中引入,本版本继续作为预览特性。新加入了两项增强改进:窄化引用转换(Narrowing Reference Conversion)不相交类型(Disjoint Types)

简单来说,这是一个关于强制类型转换的特性。之前的 Java 版本中,如果要把一个类型的变量强转为另一类型,则要求两个类型是“父子”关系,否则会是一个编译错误。但是,应该注意到有这样一个场景:一个类 A 既是类 B 的子类,又是接口 L 的实现类。因此,类 B 和接口 L 之间就存在转换的可能。但如果除了 null 外,不可能存在值同时是这两种类型,则两种类型就是不相交类型,不能进行转换。比如:

1
2
3
4
5
6
7
8
9
public sealed interface Shape permits Polygon { }
public non-sealed interface Polygon extends Shape { }
public final class UtahTeapot { }
public class Ring { }

public void work(Shape s) {
UtahTeapot u = (UtahTeapot) s; // Error
Ring r = (Ring) s; // Permitted
}

s 不能从 Shape 转为 UtahTeapot 是因为 UtahTeapotfinal 的,不可能有子类来实现 Shape 接口——即不相交。而 Ring 不是 final 的,可能有子类实现 Shape 接口。

参考

Oracle doc - Java Language Updates 16