总结
JDK 25 是最新的 LTS Java 版本,也是自 2023 年 JDK 21 发布以来的第一个 LTS 版本。它包含 18 项 JDK 增强提案,其中包括 14 项已关闭提案、3 项预览提案和 1 项孵化提案。
在本文中,您将了解:
- JEP 507 消除了对用例的自上而下限制
- JEP 512 让您更轻松地编写第一个 Java 应用程序
- JEP 513 放宽了构造函数工作方式的某些限制
- JEP 505 是 Loom 项目的一部分,目前已进入第五个预览迭代版本,它将在不同线程中运行的相关任务组视为单个工作单元
又到了九月,这意味着将按照 6 个月的发布周期再次发布一个新的 JDK 版本。这种模式效果显著,Java 的变化速度相比其 30 年历史上的任何时候都要快。自 JDK 9 以来,新功能均通过一系列 JDK 增强提案 (JEP) 来定义。JDK 25 是自 2023 年 JDK 21 发布以来的第一个长期支持 (LTS) 版本。
一些随机观察:
- JDK 25 于 2025 年发布
- JDK 24 有 24 个 JEP
- JDK 25 包含 18 个 JEP
- 这高于 13 个的平均值,略高于 JDK 21(上一个 LTS 版本)的 15 个。
JDK 25 中的 Java 语言 JEP
与往常一样,许多 JEP 涉及的功能尚未最终确定。这些预览功能(由 JEP 12 定义)和孵化模块(由 JEP 11 定义)使已完全开发的功能包含在 JDK 中,同时仍提供根据反馈修改这些功能的机会。
让我们深入了解这一最新版本,从 Java 语言的一部分开始。
| JEP | 名称 | 状态 |
|---|---|---|
| 507 | 模式中的原始类型、instanceof 和 switch | 预览 |
JEP 507 提供了模式中的原始类型、instanceof 和 switch 的第三个预览版。此功能在 JDK 23 中引入,此后一直保持不变。虽然 Java 是一种面向对象的语言,但它也支持原始值(语言中直接内置的基本数据类型),以实现更佳性能。问题在于,该语言的某些部分不允许使用原始值,因此必须使用等效的包装类来替代,这会产生对象创建和垃圾回收的必要开销。Valhalla 项目有望允许我们创建可以使用原始值作为类型参数的泛型。目前,通过允许在模式中使用原始值,难度正在降低。这对 switch 尤其是一项重大的改进。然而,要完全理解,某些边缘情况仍需额外的考量。
例如,请看以下 switch:
int x = 42;
switch (x) {
int x -> System.out.println(“int”);
byte b -> System.out.println(“byte”);
}
您期望会发生什么?
答案(至少对我来说)有点令人惊讶。
此 switch 将导致编译器错误,因为 int 类型优先于 byte 类型,使其变得不可达。
switch (x) {
Integer x -> System.out.println(“int”);
byte b -> System.out.println(“byte”);
}
在第二个 switch 中,从 int 到 Integer 的装箱转换是无条件精确的,因此编译器无法确定是否仍然有优先权。这将顺利编译和运行。
让我们看看 JDK 25 中的其他功能。
| JEP | 名称 | 状态 |
|---|---|---|
| 511 | 模块导入声明 | 已关闭,已交付 |
JEP 511 是模块导入声明。一项小改动,简化了使用单个语句导入模块所有可公开访问元素的方式。这类似于 import 语句允许对包元素使用通配符的方式。
| JEP | 名称 | 状态 |
|---|---|---|
| 512 | 压缩源文件和实例主方法 | 已关闭,已交付 |
JEP 512 是压缩源文件和实例主方法。此功能目前已确定为最终版本,并且是长期努力的一部分,旨在降低编写首个 Java 应用程序的难度。无需编写所有必要的代码来定义一个主方法为 public static void 的类,只需执行以下命令即可:
void main() {
IO.println("Hello, World!");
}
| JEP | 名称 | 状态 |
|---|---|---|
| 513 | 灵活的构造函数体 | 已关闭,已交付 |
JEP 513 是灵活的构造函数体。这放宽了关于构造函数工作方式的某些限制。以前,任何对超类或重载构造函数的调用都必须是第一个语句。现在,可以在调用之前评估某些操作(例如对参数值的测试),并有可能抛出异常。这减少了更复杂的代码并消除了不必要的方法调用。此功能在 JDK 22 中以 JEP 447(名为“灵活的构造函数体”)的预览特性形式引入,现已确定为最终版本。
切换到类库后,我们拥有以下功能:
| JEP | 名称 | 状态 |
|---|---|---|
| 470 | 加密对象的 PEM 编码 | 已关闭,已交付 |
JEP 470 是加密对象的 PEM 编码。该编码标准提供了一个 API,用于对代表加密密钥、证书和证书吊销列表的对象进行编码与解码,支持其与广泛使用的隐私增强邮件 (PEM) 传输格式之间的相互转换。
| JEP | 名称 | 状态 |
|---|---|---|
| 502 | 稳定值 | 预览 |
JEP 502 是稳定值。Java 代码开发中的一个重要讨论焦点在于如何最优地使用存储不可变值的对象。Java 一直都有 final 关键字,但它并非真正意义上的最终不可变,因为 final 字段仍然可以通过反射进行修改。稳定值 JEP 为 JVM 将其视为常量的对象引入了一个 API,因此可以享受与 final 变量相同的性能优势。此外,稳定值在初始化时提供了更大的灵活性。这是一个预览功能。
| JEP | 名称 | 状态 |
|---|---|---|
| 505 | 结构化并发 | 预览 |
JEP 505 是结构化并发,目前已进入第五个预览迭代版本。作为更广泛的 Loom 项目的一部分,结构化并发将在不同线程中运行的相关任务组视为单个工作单元,从而简化错误处理和取消,提高可靠性并增强可观测性。
| JEP | 名称 | 状态 |
|---|---|---|
| 506 | 作用域值 | 已关闭,已交付 |
JEP 506 是作用域值。这也是 Loom 项目的一部分,与结构化并发相关。作用域值使方法能够与线程内的调用方以及子线程共享不可变数据。作用域值旨在成为线程局部变量的更简单替代方案。该功能作为 JDK 21 中的预览功能引入,现已确定为最终版本。
| JEP | 名称 | 状态 |
|---|---|---|
| 508 | Vector API | 孵化版本 |
JEP 508 是 Vector API,目前已进入创纪录的第十个孵化迭代版本。Vector API 是更大的 Valhalla 项目的一部分,因此它仍然是一个孵化 API。在 Valhalla 的其他部分交付之前,此功能不会最终确定,以防需要进一步更改。此 API 为开发人员提供了一种方法,可以向 JVM 发出有关如何使用 Vector 操作(单指令多数据)的明确指令,以允许在单个时钟周期内执行多个数值操作(通常在数组上)。JVM 中的 JIT 编译器已经能够使用自动矢量化,但它并不总是能够识别可以应用自动矢量化的情况。其他实现,例如 Platform Prime 中的 Azul Falcon JIT 编译器,可以自动矢量化更多代码,从而使该 API 的价值降低。
| JEP | 名称 | 状态 |
|---|---|---|
| 510 | 密钥派生 API | 已关闭,已交付 |
JEP 510 是密钥派生 API。这是一个用于密钥派生函数 (KDF) 的 API,KDF 是用于从密钥和其他数据派生其他密钥的加密算法。该功能最初作为 JDK 24 中的预览功能引入,现已确定为最终版本。
JDK 25 还包含一些特定于 JVM 和 JDK 其他部分的功能。
| JEP | 名称 | 状态 |
|---|---|---|
| 519 | 紧凑对象标头 | 已关闭,已交付 |
JEP 519 是紧凑对象标头。在常见的 64 位平台上,JVM 使用 128 位来表示对象标头,其中包含对象在堆中的地址和各种状态位。现在已将其减少到 64 位,且功能无损失。虽然这看起来像是一个小小的变更,但它可能会产生重大影响。在常见的基准测试中,性能分析显示堆大小减少了 22%,CPU 时间减少了 8%。该功能在 JDK 24 中作为预览功能引入,现已确定为最终版本。
| JEP | 名称 | 状态 |
|---|---|---|
| 521 | 分代 Shenandoah | 已关闭,已交付 |
JEP 521 是分代 Shenandoah。Shenandoah 是由 Red Hat 开发的一种替代垃圾收集算法。最初,使用非分代堆无法为许多应用程序提供必要的性能。该功能最初作为 JDK 24 中的预览功能引入,现已确定为最终版本。其他算法(例如作为 Platform Prime 一部分的 Azul C4)可以提供更高的性能和更低的延迟。
两个 JEP 是更大的 Leyden 项目的一部分,该项目旨在减少与 JVM 应用程序相关的启动和预热时间。
| JEP | 名称 | 状态 |
|---|---|---|
| 514 | 提前命令行人体工学 | 已关闭,已交付 |
JEP 514 是提前命令行人体工学。提前加载和链接类包含在 JDK 24 中,但需要两阶段机制来生成和处理分析数据。这已得到改进,无需单独的处理阶段。
| JEP | 名称 | 状态 |
|---|---|---|
| 515 | 提前分析方法 | 已关闭,已交付 |
JEP 515 为提前分析方法。这建立在 AOT 加载和链接类以在重启应用程序时提供方法执行分析数据。其他替代方案,例如 ReadyNow(已包含在 Azul 的 Platform Prime 中),不仅提供所有这些功能,还能重用应用程序先前运行的编译代码。这样可以显著提升性能。
有三个 JEP 与内置分析工具 Java Flight Recorder (JFR) 相关。
| JEP | 名称 | 状态 |
|---|---|---|
| 509 | JFR CPU 时间分析 | 已关闭,已交付 |
JEP 509 JFR CPU 时间分析,作为一项实验性功能推出。这可以在 Linux 上捕获更准确的 CPU 时间分析信息。
| JEP | 名称 | 状态 |
|---|---|---|
| 518 | JFR 协作采样 | 已关闭,已交付 |
JEP 518 是 JFR 协作采样。这提高了 Java 线程堆栈异步采样时分析数据收集的稳定性。这是通过仅在安全点遍历调用堆栈来实现的,同时最大限度地减少安全点偏差。
| JEP | 名称 | 状态 |
|---|---|---|
| 520 | JFR 方法与跟踪 | 已关闭,已交付 |
JEP 520 是 JFR 方法计时与跟踪。这通过字节码插桩提供了方法计时与跟踪的功能。
| JEP | 名称 | 状态 |
|---|---|---|
| 503 | 移除 32 位 x86 端口 | 已关闭,已交付 |
JDK 25 中的最后一个功能是 JEP 503,移除 32 位 x86 端口。JDK 的 32 位 Windows 端口已在 JDK 24 中移除,因此移除所有 32 位端口的工作已完成。尽管仍有部分用户使用 32 位操作系统,但这些系统已非常陈旧,通常不会在不升级操作系统的情况下单独升级 JDK。
如您所见,JDK 25 包含各种各样的功能,可让开发人员和用户的工作更加轻松。JDK 25 也是二进制发行版(例如 Azul 的 Platform Core)的长期支持 (LTS) 版本。这意味着它将获得延长的维护(更新)和支持。
不妨来尝试一下吧!