Java 15 功能

跟上六个月的周期传统,在2020年3月17日发布的Java 14(/community/tutorials/java-14-features#5-text-blocks-preview)之后,我们现在有Java 15,下一个非LTS版本将于2020年9月15日发布。

Java 15 功能

以下是 Java 15 的一部分功能的快速查看:

  • 密封类(预览) – JEP 360
  • 模式匹配 instanceof (第二预览) – JEP 375
  • 记录(第二预览) – JEP 359
  • 文本块(标准) – JEP 378
  • 隐藏类 – JEP 371
  • 删除 Nashorn JavaScript 引擎 – JEP 372
  • 重新实施 Legacy DatagramSoc API – JEP 373( _*) 禁用并删除偏差锁 – JEP 374

Java 15 安装在 Mac OS 上

  • 要開始使用 Java 15,請從 這裡下載 JDK。
  • 如下所示,在 /Library/Java/JavaVirtualMachines 中複製並提取 tar 檔案:
1$ cd /Library/Java/JavaVirtualMachines
2
3$ sudo cp ~/Downloads/openjdk-15_osx-x64_bin.tar.gz /Library/Java/JavaVirtualMachines
4
5$ sudo tar xzf openjdk-15_osx-x64_bin.tar.gz
6
7$ sudo rm openjdk-15_osx-x64_bin.tar.gz

一旦完成,请使用任何文本编辑器打开bash_profile。我正在使用vim ~/.bash_profile。设置 Java15 到 JAVA_HOME 的路径,保存更改并执行源 ~/.bash_profile以反映更改。

1export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home

最后,您已经准备好使用 Java 15 编译和运行程序了。我们将使用 JShell,一个交互式的 REPL 命令行工具,以快速测试新的 Java 15 功能。

重要的是要注意,在Java 15中发布的许多功能都在预览中,这意味着虽然它们现在完全工作,但未来可能会发生更改,有些功能可能会成为标准,或者在下一个版本周期中被删除,为了测试预览功能,您需要在运行JShell或Java程序时明确设置--enable-preview,如下所示:

1jshell --enable-preview
2
3javac --release 15 --enable-preview Author.java

在接下来的几节中,让我们讨论 Java 15 中的重要语言变化。

十一、学术课(预览)

在Kotlin(社区/教程/kotlin-sealed-class)中,密封类已经存在了一段时间,Java 15终于引入了这个功能,以更好地控制继承。

正如其名称所示,密封类允许您将类等级限制或允许仅限于某些类型。

这对于模式匹配非常有用,因为你有特定数量的类可以切换

下面的语法定义了Java 15中的密封类:

1public sealed class Vehicle permits Car, Bike, Truck {
2...
3}

因此,上述代码意味着,只有允许关键字后定义的类可以扩展车辆``密封类。

如果您在与车辆相同的文件中定义了类汽车自行车卡车,您可以省略关键字权限,编译器将默认地照顾它,如下所示:

1sealed class Vehicle {...}
2
3final class Car extends Vehicle {...}
4final class Bike extends Vehicle {...}
5final class Truck extends Vehicle {...}

正如你上面所看到的,我们已经定义了每个类的最终修改器。现在,这是一个重要的密封类规则,你需要记住:每个允许的类都必须设置一个明确的修改器。

以下是各个修改剂如何影响继承:

  • 被声明为最终的允许子类不能进一步扩展.
  • 被声明为密封的允许子类可以进一步扩展,但只能由子类允许的类扩展
  • 被声明为未密封的允许子类可以进一步扩展到任何类。

在Java 15之前,开发人员只能使用最终的关键字或范围修改器来控制继承,因此,密封类在定义类等级时为Java开发人员带来了额外的灵活性。

Java 的反射 API 还获得了处理密封类的两种新方法:

1java.lang.constant.ClassDesc[] getPermittedSubclasses();
2
3boolean isSealed()

纪录片(第二次预览)

Records在Java 14中被引入为预览功能,旨在减少在编写基于POJO的数据载体类时的锅板代码。

现在,在Java 15中,记录获得了第二个预览,虽然没有任何重大变化(只有一些小额补充),但仍然有一些主要的澄清和限制,你应该知道:

  • 在 Java 15 之前,人们可以在记录中声明本地方法(虽然这不是一个好主意)。现在 JEP 明确禁止在记录中声明本地方法。 可以理解的是,定义一个本地方法会通过带来外部状态依赖而窃取记录的 USP
  • 与记录类的记录组件相符的默认声明字段是最终,现在不应该通过反射进行修改,因为它将导致IllegalAccessException

记录是指数据载体类别,您应该完全避免在其中定义本地方法。

记录与密封类型

我们知道记录是最终的,不能扩展的,幸运的是,记录可以实现界面。

因此,您可以定义密封接口,并以以下方式将其应用到您的记录中:

1sealed interface Car permits BMW, Audi { ... }
2
3record BMW(int price) implements Car { ... }
4
5record Audi(int price, String model) implements Car { ... }

地方纪录

记录也可以在中间值存储方法中定义。 与本地类不同,本地记录是默认的静态. 这意味着它们无法访问包含方法的变量和实例成员,这实际上非常好,因为它防止记录捕捉值。

本地记录对于早期需要创建辅助记录的Java开发人员来说是一个很好的好处。

了解如何引入本地记录有助于使用以下方法执行流 API 中的值计算:

 1List<Merchant> findTopMerchants(List<Merchant> merchants, int month) {
 2    // Local record
 3    record MerchantSales(Merchant merchant, double sales) {}
 4
 5    return merchants.stream()
 6        .map(merchant -> new MerchantSales(merchant, computeSales(merchant, month)))
 7        .sorted((m1, m2) -> Double.compare(m2.sales(), m1.sales()))
 8        .map(MerchantSales::merchant)
 9        .collect(toList());
10}

结论

虽然上述两种语言是Java 15中的两个主要语言功能,但我们在第二个预览中还提供用户反馈的模式匹配,现在作为标准功能的文本块,最重要的是新的隐藏类功能。

隐藏类是一种JVM功能,适用于框架开发人员,它允许通过使用Lookup::defineHiddenClass来定义类的实现,使类实现变得不可发现。

这些是Java 15所引入的主要变化。

Published At
Categories with 技术
Tagged with
comments powered by Disqus