Java 15 特性

10 Sept 2024 | 5 分钟阅读

Java 15 于 2020 年 9 月发布,带来了一系列令人兴奋的功能,提升了开发体验、性能和安全性。Java 15 于 2020 年 9 月正式发布,是 JDK 平台下一个短期支持版本。它构建于早期版本中的多项功能之上,并提供了一些新的增强功能。

为 CharSequence 添加了 isEmpty() 默认方法

在此版本中,java.lang.CharSequence 已更新,定义了一个默认的 isEmpty() 方法,用于测试字符序列是否为空。在代码中测试和过滤空字符串及其他 CharSequence 是常见的操作,可以使用 CharSequence::isEmpty 作为方法引用。实现 java.lang.CharSequence 和另一个定义了 isEmpty() 方法的接口的类应该注意此添加,因为它们可能需要修改以覆盖 isEmpty() 方法。

支持 Unicode 13.0

此版本将 Unicode 支持升级到 13.0,其中包括以下内容:

  • lang.Character 类支持 Unicode 13.0 级别的 Unicode 字符数据库,13.0 添加了 5,930 个字符,总计 143,859 个字符。这些新增内容包括 4 个新脚本,总计 154 个脚本,以及 55 个新表情符号。
  • java.text.Bidi 和 java.text.Normalizer 类分别支持 Unicode 标准附件 #9 和 #15 的 13.0 级别。
  • java.util.regex 包基于 Unicode 标准附件 #29 的 13.0 级别支持扩展组合字符。有关 Unicode 13.0 的更多详细信息。

隐藏类

Java 15 中引入了隐藏类。隐藏类对现有代码有以下影响:

Class::getName 传统上返回一个二进制名称,但对于隐藏类,它返回一个包含 ASCII 正斜杠 (/) 的字符串,因此不是二进制名称。假设返回字符串是二进制名称的程序可能需要更新以处理隐藏类。也就是说,Unsafe::defineAnonymousClass 的长期实践是定义名称不是二进制名称的类,因此某些程序可能已经成功处理了此类名称。

对于隐藏类,Class::descriptorStringMethodType::descriptorString 返回一个包含 ASCII 点 (.) 的字符串,因此不是符合 JVMS 4.3 的类型描述符。假设返回字符串是符合 JVMS 4.3 的类型描述符的程序可能需要更新以处理隐藏类。

Class::getNestMembers 已更改为在验证任何列在 NestMembers 属性中的成员的嵌套成员资格失败时不再抛出异常。相反,Class::getNestMembers 返回嵌套主机以及嵌套成员属性中成功解析并确定与该类具有相同嵌套主机的成员。 (这意味着它可能返回比嵌套成员属性中列出的成员更少的成员。)预期在嵌套成员资格错误时抛出 LinkageError 的现有代码可能会受到影响。

JVM 中嵌套成员的测试已更改为在嵌套成员资格无效时只抛出 IllegalAccessError。需要一些历史理解。

在 Java 8 中,所有访问控制失败都通过 IllegalAccessError (IAE) 信号。此外,如果给定的访问检查一次因 IAE 而失败,那么相同的检查每次都会因 IAE 而失败。

在 Java 11 中,嵌套成员(JEP 181)的引入意味着访问控制失败可以由 IllegalAccessError 信号,或者如果嵌套成员资格无效,则由 LinkageError 信号。尽管如此,如果给定的访问检查因特定异常而失败,那么相同的检查总是会因相同的异常而失败。

在 Java 15 中,Lookup::defineHiddenClass 的引入意味着查找类的嵌套主机必须在定义隐藏类作为查找类的嵌套成员时就被急切地确定。Lookup::defineHiddenClass 和 Class::getNestHost 都以比 Java 11 中的 JVM 更具弹性的方式确定类的嵌套主机;即,当类声称的嵌套成员资格无效时,API 简单地将该类视为自托管。为了与 API 保持一致,JVM 不再在类的嵌套成员资格无效时抛出 LinkageError,而是将该类视为自托管。这意味着 JVM 只从访问控制抛出 IAE(因为自托管类不允许任何其他类访问其私有成员)。这是绝大多数用户代码所期望的行为。

JVM TI GetClassSignature 返回一个包含 ASCII 点 (.) 的字符串,用于隐藏类。如果 JVM TI 代理假定 GetClassSignature 返回的字符串是符合 JVMS 4.3 的类型描述符,则可能需要更新以处理隐藏类。

添加了对 SO_INCOMING_NAPI_ID 的支持

此版本已在 jdk.net.ExtendedSocketOptions 中添加了一个新的 JDK 特定套接字选项 SO_INCOMING_NAPI_ID。该套接字选项是 Linux 特有的,它允许应用程序查询与其套接字连接关联的底层设备的 NAPI(New API)ID,并利用高性能网络接口卡(NIC)设备的应用程序设备队列(ADQ)功能。

TreeMap 类方法的专用实现

TreeMap 类现在提供了 putIfAbsent()、computeIfAbsent()、computeIfPresent()、compute() 和 merge 方法的覆盖实现。新的实现提供了性能改进。但是,如果为 compute 或 merge 方法提供的函数修改了映射,则可能会抛出 ConcurrentModificationException,因为禁止为这些方法提供的函数修改映射。如果发生 ConcurrentModificationException,则必须更改函数以避免修改映射,或者应重写周围的代码,用 get 和 put 等常规 Map 方法替换 compute 和 merge 方法的使用。

文本块

Java 语言中添加了文本块。文本块是一种多行字符串字面量,它消除了对大多数转义序列的需求,以可预测的方式自动格式化字符串,并允许开发人员在需要时控制格式。

垃圾回收器

在 Java 15 中,ZGC (JEP 377) 和 Shenandoah (JEP 379) 将不再是实验性的。两者都将是团队可以选择使用的支持配置,而 G1 收集器将保持默认。之前都可以通过实验性功能标志来使用。这种方法允许开发人员测试新的垃圾收集器并提交反馈,而无需下载单独的 JDK 或附加组件。关于 Shenandoah 的一个注意事项:它并非在所有供应商的 JDK 中都可用——尤其是 Oracle JDK 不包含它。

结论

Java 15 在此基础上集成了 past releases 的多项功能,包括 records、text blocks、新的垃圾收集算法等。它还添加了新的预览功能,包括 sealed classes 和 hidden classes。由于 Java 15 不是长期支持版本,我们可以预计其支持将于 2021 年 3 月结束。届时,我们可以期待 Java 16 的发布,随后不久将迎来新的长期支持版本 Java 17。


下一主题Java CLOB