Java 25 - 生产力与运行时演进
📑 Java 演进系列:总览 | Java 8 | Java 11 | Java 17 | Java 21 | Java 25
Java 25 于 2025 年 9 月 16 日 GA,是继 Java 21 之后的 LTS 版本,按 Oracle 的支持路线图获得长期支持。它的主线是生产力与运行时间的双线演进:语言层面定型了紧凑源文件、模块导入声明与灵活构造器主体,把"写一个可运行 Java 程序"的样板成本降到历史最低;API 层面补齐了作用域值与标准密钥派生函数接口;HotSpot 则交付了紧凑对象头、分代 Shenandoah 与 AOT 命令行人机工程学。更全面的特性盘点可参阅Java 25 特性专题。
紧凑源文件与实例 main 方法
JEP 512(正式特性,历经 JEP 445、463、477、495 四轮预览后定稿)允许省略 class 声明与 public static void main(String[] args) 样板:未显式声明类的源文件会得到一个隐式声明的类,成员可保留实例语义,java.io.IO 按需自动导入。
1 | |
1 | |
main 方法还支持实例形式:非静态、参数可省略、字段是实例字段,程序状态直接落在对象上,适合教学与小工具。
1 | |
旧的静态 main 签名完全兼容不受影响;简洁写法只影响新代码的表达方式。
模块导入声明
JEP 511(正式特性)新增 import module:一条语句导入目标模块导出的全部包。以 import module java.base; 为例,List、Map、Executor 等常用类型无需再逐包导入。
1 | |
模块导入可与普通单类型导入、按需导入混用;当两个模块导出同名简单类型时,冲突仍需显式普通导入消歧。依赖第三方模块时,模块导入同样适用,前提是该模块已在类路径或模块路径上。
灵活构造器主体
JEP 513(正式特性)允许在 super(...) 调用之前编写语句——此前"先校验参数、快速失败"只能放在 super 之后,或改用静态工厂绕开。提前语句的限制是不得访问未构造完成的实例:不能引用 this、实例字段或实例方法;但可以校验参数、读取静态成员、准备局部变量。
1 | |
价值在于"失败早于副作用":父类构造器可能已做日志、注册等有副作用的工作,提前校验保证无效参数绝不触发它们。
作用域值
JEP 506(正式特性)定型了 ScopedValue:不可变、生命周期严格绑定语法作用域的上下文传递机制,目标是替代 ThreadLocal。值通过 ScopedValue.where(...).run(...) 绑定,仅在 run 的词法范围内可见,结束即自动清理,无需 remove,也不会泄漏到线程池中的下一个任务。
1 | |
作用域内可以再次 where(...).run(...) 重绑定以临时遮蔽外层值。与虚拟线程、结构化并发配合时,作用域值会被 fork 出的子任务自动继承,且绑定开销远低于 ThreadLocal 的线程本地存储表——迁移建议:只读上下文用 ScopedValue,确需可变线程状态才保留 ThreadLocal。
密钥派生函数 API
JEP 510(正式特性)为密钥派生函数(KDF)提供标准 API:新类 javax.crypto.KDF 负责"实例化 + 派生"两步,随 API 附带 HKDF 实现(RFC 5869)。它补上了此前只能靠 SecretKeyFactory 勉强表达 KDF 的缺口,也是 KEM(JEP 452)之后向 HPKE、后量子和混合加密演进的第二块拼图。
1 | |
deriveData(...) 变体返回裸字节数组,用于需要熵而非密钥对象的场景。PBKDF2 不在迁移范围内:它仍走既有的 SecretKeyFactory 通道。
预览与孵化特性
Java 25 仍有一批预览与孵化特性,API 形态未定稿,进入生产前必须评估后续版本的不兼容成本。命令行必须显式开启:
1 | |
- 原始类型模式(JEP 507,第三次预览):
instanceof与switch支持原始类型模式,装箱值自动拆箱参与匹配。
1 | |
- 稳定值(JEP 502,预览):
StableValue延迟初始化且值不可变,JVM 可据此做常量折叠等优化。
1 | |
- 结构化并发(JEP 505,第五次预览):
StructuredTaskScope.open()把并发子任务的生命周期约束在语法作用域内,任一失败即取消其余。
1 | |
- Vector API(JEP 508,第十次孵化):
jdk.incubator.vector模块中的 SIMD 向量计算 API,依赖 Valhalla 的值对象落地后才会转正,目前仅供评估性能收益。
HotSpot 运行时改进(HotSpot/JDK)
以下均为 HotSpot/JDK 实现层面的能力,不是 Java SE 语言或 API 保证,可用性取决于具体发行版与虚拟机选项。
- 紧凑对象头(JEP 519):64 位平台上对象头由 12/16 字节压缩到 8 字节,对象密集型负载的堆占用显著下降(SPECjbb2015 实测堆省约 22%)。非默认布局,需显式开启:
1 | |
- 分代 Shenandoah(JEP 521):JDK 24 以实验特性引入的分代模式在 Java 25 转正,按分代假设单独回收年轻代,改善吞吐与内存利用率,同时保持低停顿目标。非默认模式:
1 | |
- AOT 命令人机工程学(JEP 514):在 JEP 483 两步工作流(record 训练、create 生成)之上,提供一步生成 AOT 缓存的简化入口,加速应用启动:
1 | |
常用特性总结
- 紧凑源文件:
void main() { ... }+ 自动导入的IO,小工具与脚本零样板。 - 实例 main 方法:非静态入口,程序状态即实例字段。
- 模块导入声明:
import module java.base;一次导入整模块的导出包。 - 灵活构造器主体:
super(...)之前即可校验参数、快速失败。 - 作用域值:
ScopedValue.where(...).run(...)替代ThreadLocal的只读上下文传递。 - KDF API:
KDF.getInstance("HKDF-SHA256")标准化派生密钥。 - 预览/孵化:原始类型模式、稳定值、结构化并发需
--enable-preview;Vector API 需--add-modules jdk.incubator.vector。 - HotSpot/JDK:紧凑对象头、分代 Shenandoah、AOT 缓存改善内存占用与启动速度。
迁移与兼容性
从 Java 21 升级到 Java 25 通常是低风险的:语言与 API 变化以新增为主,无破坏性语法变更,旧的静态 main 入口完全兼容。需要注意的点:模块导入与逐包导入可共存,同名冲突时以显式普通导入消歧;构造器提前语句禁止访问未构造实例,迁移校验逻辑时保持纯函数式写法,不碰 this 与实例成员;ScopedValue 不可变,依赖 ThreadLocal 可变写线程的存量代码需要重构而非平移。预览特性(原始类型模式、稳定值、结构化并发)与孵化的 Vector API 仍在演进,生产采用前应接受 --enable-preview 的锁定成本并跟踪后续版本变化。紧凑对象头、分代 Shenandoah、AOT 缓存属于部署调优项,不应写入依赖 Java SE 规范的代码假设。






