Java17于2021年9月发布,是一个LTS(long term support)长期支持的版本,根据计划来看Java17会支持到2029年(java8会支持到2030年,OMG),同时Oracle提议下一个LTS版本是Java21,在2023年9月发布。 stickPicture.pngstickPicture.png 现在很多新的Java 开发框架和类库支持的最低JDK 版本就是 17 (比如 AI 开发框架 LangChain4j)。

正式特性

Sealed Classes

在jdk15中已经添加了Sealed Classes,只不过当时是作为预览版,经历了2个版本之后,在jdk17中Sealed Classes已经成为正式版了。Sealed Classes的作用是可以限制一个类或者接口可以由哪些子类继承或者实现。

在很多 Java 开发者的印象中,一个类要么完全开放继承(任何类都能继承),要么完全禁止继承(final 类)。

其实这样是没办法精确控制继承关系的,在设计 API 或领域模型时可能会遇到问题。Java 17 将 Sealed 密封类转正,让类的继承关系变得更可控和安全。

比如可以只允许某几个类继承

但是,被允许继承的子类必须选择一种继承策略

  1. final:到我为止,不能再继承了

  2. sealed:我也要控制谁能继承我

  3. non-sealed:我开放继承,任何人都可以继承我

强制声明继承策略是为了 确保设计控制权的完整传递。如果不强制声明,sealed 类精确控制继承的价值就会被破坏,任何人都可以通过继承子类来绕过原始设计的限制。

注意,虽然看起来 non-sealed 打破了这个设计,但这也是设计者的主动选择。如果不需要强制声明,设计者可能会无意中失去控制权。

有了 Sealed 类后,某个接口可能的实现类型就尽在掌握了,可以让 switch 模式匹配变得更加安全

密封类的实际应用

增强的伪随机数生成器

Java 17 引入了全新的随机数生成器 API,提供了更优的性能和更多的算法选择

增加了伪随机数相关的类和接口来让开发者使用stream流进行操作

  • RandomGenerator

  • RandomGeneratorFactory

之前的java.util.Random和java.util.concurrent.ThreadLocalRandom都是RandomGenerator接口的实现类。

新的随机数生成器特性

新 API 的优势

  • 更多算法:支持多种高质量的 PRNG 算法

  • 更好性能:针对现代 CPU 优化

  • 功能丰富:支持跳跃、分割等高级功能

  • 统一接口:所有算法使用相同的 API

强封装 JDK 内部 API

Java 17 进一步强化了对 JDK 内部 API 的封装,一些之前可以通过反射访问的内部类现在完全不可访问,比如:

  • sun.misc.Unsafe

  • com.sun.*包下的类

  • jdk.internal.*包下的类

虽然这提高了 JDK 的安全性和稳定性,但可能需要迁移一些依赖内部 API 的老代码。

恢复始终严格的浮点语义

Java 17 恢复了严格的浮点计算语义,确保跨平台的一致性

新的 macOs 渲染管道

Java 17 在 macOS 上使用新的渲染管道,提供更好的性能和兼容性

macOS/AArch64 端口

Java 17 正式支持 Apple Silicon(M1/M2)芯片

弃用 Applet API

Java 17 将 Applet APl标记为弃用并计划删除

上下文特定的反序列化过滤器

Java 17 增强了反序列化安全性

并发标记清除收集器完全移除

去除了AOT和JIT

AOT(Ahead-of-Time)是Java9中新增的功能,可以先将应用中的字节码编译成机器码。

Graal编译器作为使用java开发的JIT(just-in-time )即时编译器在java10中加入(注意这里的JIT不是之前java中的JIT,在JEP 317中有说明https://openjdk.java.net/jeps/317)。

以上两项功能由于使用量较少,且需要花费很多精力来维护,因此在java17中被移除了。当然你可以通过Graal VM来继续使用这些功能。

预览特性

switch语法的变化(预览)

在之前版本中新增的instanceof 模式匹配的特性在switch中也支持了,即我们可以在switch中减少强转的操作。比如下面的代码:

Rabbit和Bird均实现了Animal接口

新特性可以减少Animal强转操作代码的编写:

与密封类结合:

孵化器特性

外部函数和内存 API(孵化器)

Java 17 继续完善外部函数和内存 API

向量 API(第二次孵化器)

Java 17 继续改进向量 API