JDK 18:Java 18的新功能
将于2022年3月发布的Java 18将孵化出一个矢量API,预览开关语句的模式匹配,采用UTF-8作为默认字符集,并包括一个简单的Web服务器。
Java开发工具包(JDK)18定于2022年3月22日发布。新版本的标准Java将有9个新功能,该功能集已于12月9日冻结。
从1月20日开始,该版本已经进入了第二轮降级阶段,此前的最初降级阶段是在上个月开始的。标准Java的升级版每六个月发布一次,最新的JDK 17于9月发布。
OpenJDK页面列出了以下正式针对JDK 18的功能:服务提供者接口、简单的Web服务器、矢量API、代码片段、核心反射的重新实现、UTF-8字符集、外国函数和内存API的第二个孵化器、开关语句的模式匹配的第二个预览,以及最后增加的最终化的废弃。
JDK 18的候选版本将在2月10日和2月24日发布。JDK 17是一个长期支持(LTS)版本,将从Oracle获得至少八年的支持,而JDK 18将是一个短期功能版本,支持期为六个月。JDK 18的早期访问版本可以在java.net上找到Linux、Windows和MacOS的版本。
JDK 18提案的具体内容包括:
- 废弃finalization,以便在未来的版本中删除。Finalizer存在缺陷,在安全性、性能、可靠性和可维护性方面造成了重大的实际问题。它也有一个困难的编程模型。Finalization目前是默认启用的,但可以被禁用,以方便早期测试。它将在一个功能版本中被默认禁用,并在以后的版本中完全删除。该提案要求提供一个命令行选项来禁用最终化,并在标准Java API中废弃所有最终化器和最终化方法。该提案的目标包括帮助开发者了解最终化的危险,为最终移除最终化做好准备,并提供简单的工具来帮助检测对最终化的依赖。在Java 1.0中引入的最终化是为了帮助避免资源泄漏。一个类可以声明一个终结者--方法
protected void finalize()--其主体释放任何基础资源。垃圾收集器会在回收对象内存之前安排调用无法到达的对象的终结器;反过来,finalize方法可以采取一些行动,如调用对象的close。这似乎是防止资源泄漏的一个有效的安全网,但存在的缺陷包括不可预测的延迟,从一个对象变得不可到达到调用它的终结者之间有很长的时间;不受约束的行为,终结者代码可以采取任何行动,包括复活一个对象并使其再次可达;终结者总是被启用,没有明确的注册机制;终结者可以以任意的顺序在未指定的线程上运行。鉴于终结器的问题,建议开发者使用其他技术来避免资源泄漏,即 try-with-resources 语句和清洁器。(详见JDK增强建议421)。 - 对于互联网地址解析SPI,建议为主机和名称地址解析定义一个SPI,以便
Inet.Address,可以使用平台内置解析器以外的解析器。这项工作的动机包括更好地启用Project Loom,用于Java中的并发和新的编程模型,以及整合新的网络协议、定制和启用测试。该建议不涉及为JDK开发一个替代的解析器。 - 对
switch的模式匹配的第二次预览,其中Java语言将通过对switch表达式和语句的模式匹配,以及对模式语言的扩展来增强。这在JDK 17中进行了预览。将模式匹配扩展到switch,允许一个表达式针对一些模式进行测试,每个模式都有一个特定的动作,因此复杂的面向数据的查询可以被简洁而安全地表达。 - 带方法句柄的核心反射的重新实现将在
lang.reflect.Method、Constructor、Field、java.lang.invoke方法句柄的基础上重新实现。让方法句柄作为反射的底层机制将减少java.lang.reflect和java.lang.invokeAPI的维护和开发成本。 - 在简单网络服务器的建议中,将提供一个命令行工具来启动一个最小的网络服务器,只提供静态文件。没有CGI或类似servlet的功能。该工具将对原型设计、临时编码和测试非常有用,特别是在教育背景下。该计划的目标包括提供一个开箱即用的静态HTTP文件服务器,具有简单的设置和最小的功能,减少开发人员的激活能量,使JDK更加平易近人,并通过命令行提供一个默认的实现,同时提供一个小型的API用于程序化创建和定制。提供一个功能丰富的或商业级的服务器并不是本提案的目标。
- 第二次孵化外国函数和内存API,其中引入了一个API,通过这个API,Java程序可以与Java运行时之外的代码和数据进行互操作。通过调用外来函数(JVM之外的代码)和安全地访问外来内存(不由JVM管理的内存),该API让Java程序调用本地库和处理本地数据,而没有JNI(Java Native Interface)的脆性和危险。其目的是用一个卓越的、纯粹的Java开发模型来取代JNI。这个API是在JDK 17中孵化的。对于JDK 18,将根据反馈意见进行改进,如支持更多的载体,如内存访问var句柄中的Boolean和MemoryAddress,以及将Java数组复制到内存段或从内存段复制的新API。
- 矢量API将在JDK 18中进行第三次孵化,之前已经在JDK 16和JDK 17中孵化。这项建议将表达矢量计算,在运行时编译为支持的CPU架构上的最佳矢量指令,实现优于同等标量计算的性能。矢量运算表达了一定程度的并行化,使更多的工作可以在一个CPU周期内完成,从而产生显著的性能改进。与平台无关的矢量API旨在提供一种在Java中编写复杂算法的方法,使用现有的HotSpot自动矢量器,但有一个用户模型,使矢量化更加可预测。JDK 18还将增加对ARM Scalar Vector Extension平台的支持,并提高在硬件中支持屏蔽的架构上接受屏蔽的矢量操作的性能。
- 将UTF-8指定为标准Java APIs的默认字符集。UTF-8是一种用于电子通信的可变范围的字符编码,被认为是网络的标准字符集。字符集是能够对网络上的所有字符进行编码的字符编码。通过这一改变,依赖于默认字符集的API将在所有的实现、操作系统、地区和配置中表现一致。该建议无意于定义新的Java标准或JDK特定的API。该建议的支持者认为,许多环境中的应用程序不会受到Java选择UTF-8的影响,因为MacOS、许多Linux发行版和许多服务器应用程序已经支持UTF-8。然而,在其他环境中存在风险,最明显的是依赖默认字符集的应用程序在处理默认字符集未被指定时产生的数据时将表现得不正确。数据损坏可能会悄悄发生。预计主要影响将落在亚洲地区的Windows系统用户身上,可能还有亚洲和其他地区的一些服务器环境。
- Java API文档中的代码片段,涉及为JavaDoc的标准Doclet引入一个
@snippet标签,以简化API文档中的示例源代码。该计划的目标之一是通过提供对源代码片段的API访问,促进对这些片段的验证。虽然正确性是作者的责任,但在JavaDoc和相关工具中加强支持可以使其更容易实现。其他目标包括启用现代风格,如语法高亮,以及名称与声明的自动联系,并使IDE对创建和编辑片段有更好的支持。该提案指出,API文档的作者经常在文档注释中包含源代码的片段。