• Java 21正式发布 快来看看都有哪些新特性
  • 发布于 2个月前
  • 479 热度
    0 评论
Oracle 高兴地宣布 JDK 21 已经正式上线了。这是按照每六个月一次的发布计划,准时推出的第 12 个版本。这种定期的发布模式为开发者提供了稳定和可预见的创新,使得他们可以轻松地接纳和采用这些新特性。Java 由于其出色的性能、稳定性和安全性使其持续成为全球最受欢迎的编程语言。

JDK 21 已经正式发布
Oracle 现已为开发者、终端用户及企业推出 JDK 21。

Oracle 承诺为 Java 21 提供最少八年的长期支持。这长达八年的支持期为各大机构提供了足够的灵活性,使其可以在较少维护的情况下更长时间地运行应用,并能够按照自己的节奏进行迁移。依据客户的反馈及其在 Java 生态中的应用,Oracle 还决定将 Java 11 的长期支持期延长到至少 2032 年 1 月,这意味着 Oracle 将提供至少额外的八年支持和更新。

Java 21,携手前行
如同先前版本一样,Java 21 对 OpenJDK 社区中许多个人和组织的贡献表示庆祝 —— 我们共同构建了 Java!

JDK 21 的修复率
尽管多年来 JDK 版本的变动速度大体上一直维持稳定,但在六个月的发布周期中,准备投入生产的功能和改进的发布速度大大提升了。与我们过去的主要版本相比,不再是每隔几年做上万次的修复和近百次的 JEP(JDK 增强提议)发布,现在更倾向于在更可控、更具可预测性的六个月周期内,以精简的特性版本发布这些增强。

这些变化从重大新特性,到小的改进,再到日常维护、缺陷修复和文档完善都有涵盖。每一个变更在 JDK Bug System 中都以单一的提交对应一个特定问题表示。

在 Java 11 到 Java 21 的 GA 时间段内,有 24,196 个 JIRA 问题被标记为已修复,其中 17,288 个是由 Oracle 的人员完成的,而另外的 6,908 个则由独立开发者或其他组织的开发者所贡献。深入研究这些问题,并从任务分配者中整合出的组织数据,我们得到了一个展示各个组织在 Java 开发中贡献度的图表:

在 Java 21 中,共有 2,585 个 JIRA 问题被标为已修复。其中,1,868 个问题是由 Oracle 解决的,而另外的 717 个则是由 Java 社区的其他成员所贡献。Oracle 特此感谢在这方面做出重要贡献的各大公司和开发者,包括 Amazon、ARM、Azul、Google、华为、IBM、Intel、ISCAS、Red Hat、Rivos、SAP 以及腾讯。我们也很高兴看到 Bellsoft 和 Loongson 这样的小型组织,以及独立的开发者们所做的贡献,他们在 Java 21 中总共贡献了 8% 的修复。

此外,借助 OpenJDK 质量外展项目,我们还要感谢以下 FOSS 项目。他们在 Java 21 的早期访问构建中提供了宝贵的反馈,帮助我们提高了发布版本的质量:
Apache Commons
Apache ZooKeeper
AssertJ
BNYM Code Katas
JUnit5
Karate

MyBatis


Java 21 新特性
除了众多的性能、稳定性和安全性更新,Java 21 还引入了大量新功能和增强。其中 15 个增强足够重要,以至于它们都有自己的 JDK 增强提议 —— JEP,包括六个预览特性和一个孵化特性。

1、结构化并发,在预览阶段,旨在通过结构化并发的 API 简化并发编程,将在不同线程运行的相关任务视为一个工作单元。这种方式可以更加简洁地进行错误处理和任务取消,提高其可靠性,并增加对并发任务的观察能力。结构化并发在 JDK 20 和 JDK 19 中曾经进行过孵化,分别发布于 2022 年的 3 月和 9 月。

现在,它将作为 java.util.concurrent 包中的预览 API 提供。本次主要变化是 StructuredTaskScope::Fork(…) 方法返回的是 [Subtask],而非 Future。结构化并发的目标是推广并发编程风格,减少因任务取消和结束时出现的问题,如线程泄露和取消延迟,同时提高并发代码的可观测性。

2、作用域值,也在预览中,能在线程之间或线程内部共享不可变数据。它们相较于线程局部变量,特别是在大量使用虚拟线程时,更为推荐。线程局部变量存在一些设计上的缺陷,如不受限的可变性、无限制的生命周期和昂贵的数据继承。

作用域值允许在大型应用程序的组件间安全地共享数据,避免依赖方法参数。此提议在 JDK 20 中进行了孵化。它的目标包括简易性、可理解性、健壮性以及高效性。

3、有一个提议考虑未来禁止动态加载代理,并呼吁在代理动态加载到正在运行的 JVM 时发出警告。此举的目的是为了在未来的版本中默认不允许动态加载代理,从而提高系统的完整性。该提议的其他目的包括:重新评估即时修改运行代码的可维护性与假设代码不被随意修改的完整性之间的权衡,确保多数工具(不需要动态加载代理的)不受此改变的影响。

此提议还要求能动态加载代理的功能与其他 “超能力” 如深度反射相匹配。代理可以在应用程序运行时修改其代码;它们最初在 2004 年的 JDK 5 中被引入,用于工具(例如性能分析器)来对类进行插桩。尽管代理最初是为无害的插桩而设计,但高级开发者找到了其他用例,例如面向切面编程,这可能以随意的方式改变应用的行为。同时,没有什么能阻止代理更改应用之外的代码,如 JDK 自身。

从 JDK 5 开始,系统需要代理在命令行上明确指定,以确保应用的所有者同意使用代理。在 JDK 21 的计划中,将要求动态加载的代理得到应用所有者的批准,就像在启动时加载代理那样。这个变动将使 Java 平台更倾向于默认完整性。

4、一个用于密钥封装机制的 API,这是一种通过公共密码学来保护对称密钥的加密技术。该提案的一个目标是使应用程序能够使用 KEM 算法,例如 RSA 密钥封装机制(RSA-KEM)、椭圆曲线综合加密方案(ECIES)以及美国国家标准与技术研究所(NIST)后量子密码学标准化过程中的候选算法。

另一个目标是使 KEM 在更高级别的协议,如传输层安全性(TLS),以及加密方案,如混合公钥加密(HPKE)中能够使用。安全提供者可以使用 Java 代码或本地代码来实现 KEM 算法,并包括在 RFC 9180 中定义的 Diffie-Hellman KEM(DHKEM)的实现。

5、弃用 Windows 32 位 x86 端口并计划在未来版本中移除,旨在更新构建系统,当尝试配置 Windows 32 位 x86 的构建时,将发出错误消息。通过新的配置选项可以抑制此消息。此外,计划在相关文档中将该端口和相关的端口特定功能标记为弃用,以便将来删除。提案指出,Windows 10 是最后一个支持 32 位操作的 Windows 操作系统,将于 2025 年 10 月结束生命周期。

6、未命名类和实例主方法的预览旨在演进 Java 语言,以便学生能够编写他们的第一个 Java 程序,而无需理解为大型程序设计而设计的语言特性。学生可以编写简化的单类程序声明,然后随着技能的提高,无缝地扩展程序以使用更高级的功能,而不需要使用不同的 Java 方言。该提案不仅提供了学习 Java 的平滑过渡,还减少了编写简单 Java 程序(如脚本和命令行工具)所需的繁文缛节。

7、未命名模式和变量的预览。未命名模式用于匹配记录组件,而无需声明组件的名称或类型,而未命名变量可以初始化但不能使用。这两者都以下划线字符 “_” 表示。此提案旨在通过省略不必要的嵌套模式来提高记录模式的可读性,并通过识别必须声明但不会使用的变量来提高所有代码的可维护性。

8、分代 ZGC 旨在通过扩展 ZGC 以维护新旧对象的不同代,从而提高应用程序的性能。新对象往往寿命较短;维护不同代将允许 ZGC 更频繁地收集新对象。使用分代 ZGC 的应用程序应该会获得以下好处:较低的分配停顿风险、较低的堆内存开销以及较低的垃圾收集 CPU 开销。与非分代 ZGC 相比,这些好处应该可以在不显著降低吞吐量的情况下实现。

9、记录模式,在 JDK 19 和 JDK 20 中均有预览,旨在解构记录值。记录模式和类型模式可以嵌套使用,以实现强大、声明性和可组合的数据导航和处理形式。

该提案的目标包括将模式匹配扩展到解构记录类的实例并添加嵌套模式,从而实现更可组合的数据查询。这个功能已经与 switch 表达式和语句的模式匹配共同演进(请参见下文)。当前的 JEP(JDK 增强提案)中的记录模式提案将在持续的经验和反馈基础上进一步完善此功能。除了一些小的编辑更改外,自第二次预览以来的主要变化是删除了记录模式在增强 for 语句的头部中出现的支持。该功能可能会在未来的 JEP 中重新提出。

10、Switch 模式匹配允许对一系列模式进行测试,每个模式都具有特定的操作,从而可以安全且简洁地表达复杂的面向数据的查询。这个功能最初在 JDK 17 中提出,随后在 JDK 18、JDK 19 和 JDK 20 中得到进一步完善。它将在 JDK 21 中得到最终定稿,并根据反馈和经验进行进一步改进。

与之前的 JEP 相比,主要的变化包括删除了带括号的模式,并允许在 switch 表达式和语句中使用限定的枚举常量,例如在 switch 表达式和语句中的 case 标签中使用。

该提案的目标包括通过允许模式出现在 case 标签中,扩展 switch 表达式和语句的表现力和适用性,允许在需要时减轻 switch 对 null 的历史敌意,以及通过要求模式 switch 语句覆盖所有潜在的输入值,提高 switch 语句的安全性。

另一个目标是确保现有的 switch 表达式和语句继续编译并以相同的语义执行,无需进行任何更改。

11、矢量 API 的第六个孵化版本。该 API 表达了可靠地编译为受支持 CPU 架构上的最佳矢量指令的矢量计算,从而实现了与等效标量计算相比更出色的性能。矢量 API 先前在 JDK 16 到 JDK 20 中进行了孵化。这个最新版本包括性能增强和错误修复。

该提案的目标包括清晰简洁、跨平台,并在 x64 和 AArch64 架构上提供可靠的运行时编译和性能。其他目标包括在无法将矢量计算完全表示为一系列矢量指令时进行优雅降级。

12、外部函数和内存 API 的第三次预览,使得 Java 程序能够与 Java 运行时之外的代码和数据进行互操作。通过高效调用外部函数和安全访问外部内存,这个 API 使得 Java 程序可以调用本地库并处理本地数据,而不像 JNI(Java Native Interface)那样脆弱和危险。该 API 先前在 JDK 20 和 JDK 19 中进行了预览。JDK 21 预览版中的改进包括增强了布局路径,引入了新的元素以解除地址布局,集中管理了 Arena 接口中本地段的生命周期,提供了备用的本地链接器实现,并移除了 VaList。该提案的目标包括易用性、性能、通用性和安全性。不打算通过此 API 重新实现 JNI 或以任何方式更改 JNI。

13、虚拟线程是一种轻量级线程,承诺显著减少编写、维护和观察高吞吐量并发应用程序的工作量。该计划的目标包括使以简单的按请求分配线程方式编写的服务器应用程序能够充分利用硬件资源,使现有使用 lang。Thread API 的代码能够以最小的修改采用虚拟线程,并且通过当前的 JDK 工具轻松进行虚拟线程的调试和性能分析。

虚拟线程此前在 JDK 20 和 JDK 19 中进行了预览,将在 JDK 21 中进行最终定稿。在 JDK 21 中,虚拟线程现在始终支持线程本地变量,不再允许创建没有这些变量的虚拟线程。有保证的线程本地变量支持确保更多现有库可以无需修改与虚拟线程一起使用,并有助于将面向任务的代码迁移到虚拟线程。

14、顺序集合提案引入了表示具有明确定义的遍历顺序的集合的接口。每个集合都有明确定义的第一个元素、第二个元素,依此类推,一直到最后一个元素。提供了统一的 API,用于获取第一个和最后一个元素以及以相反的顺序处理元素。

这个提案的动机是 Java 的集合框架缺乏一种集合类型来表示具有明确定义的遍历顺序的元素序列,并且缺乏适用于这些集合的统一操作。这些缺陷一直是问题并引起了投诉。该提案要求定义用于顺序集合、集合和映射的接口,并将这些接口整合到现有的集合类型层次结构中。所有这些新方法都具有默认实现。

15、字符串模板是 JDK 21 中的一个预览特性,它通过将文字文本与嵌入式表达式和处理器耦合在一起,以生成特定的结果,以补充 Java 现有的字符串字面值和文本块。这个语言特性和 API 旨在通过轻松表达在运行时计算的值的字符串来简化 Java 程序的编写。

它承诺提高表达式的可读性,改善程序的安全性,保留灵活性,并简化接受非 Java 语言中编写的字符串的 API 的使用。还有一个目标是启用开发非字符串表达式,这些表达式由文字文本和嵌入式表达式组合而成。

用户评论