
JJDK 25 作为 Java 的下一个长期支持版本LTS计划于 2025 年 9 月16日正式发布。该版本聚焦语言表达力提升、性能优化、并发模型革新及安全增强是继 JDK 21 后的首个 LTS 版本。共18个JEP。font stylecolor:rgb(77, 77, 77);/fontfont stylecolor:rgb(77, 77, 77);/font1.1 简化main方法简化 Java 程序入口支持无类声明的 void main() 方法无需 public static 修饰符新版写法// 无需显式类声明 void main() { IO.println(Hello, JDK 25!); // java.lang.IO 自动导入 String name IO.readLine(Enter your name: ); IO.println(Hello, name); }老版写法import java.util.Scanner; public class Main { public static void main(String[] args) { System.out.println(Hello, JDK 8!); Scanner scanner new Scanner(System.in); System.out.print(Enter your name: ); String name scanner.nextLine(); System.out.println(Hello, name); } }大幅降低 Java 学习门槛适合脚本编写和快速原型开发让初学者能更轻松地编写第一个程序font stylecolor:rgb(44, 62, 80);/font1.2灵活的构造函数体允许在 super() 或 this() 调用前执行初始化逻辑如参数校验font stylecolor:rgb(44, 62, 80);/font新版写法class User { private int age; User(int age) { // 初始化前置 if (age 18 || age 67) throw new IllegalArgumentException(Age must be between 18 and 67); super(); // super() 调用可不再强制首行 } }font stylecolor:rgb(44, 62, 80);/font老版写法class User { private int age; User(int age) { super(); // 必须为第一行 // 前置初始化逻辑需移到 super() 之后 if (age 18 || age 67) { throw new IllegalArgumentException(Age must be between 18 and 67); } this.age age; // 显式赋值 } }确保继承链的初始化顺序从Object到最终子类逐层初始化内存安全子类使用任何继承的成员前父类必须完全初始化防止重复初始化避免父类构造函数被多次调用font stylecolor:rgb(44, 62, 80);/font提升代码可读性和灵活性避免将校验逻辑提取到静态方法的模板代码增强对象构建时的安全性font stylecolor:rgb(44, 62, 80);/fontfont stylecolor:rgb(44, 62, 80);/font1.3 模块一次性导入预览特性]允许通过 import module 一次性导入模块的所有公共类新版写法import module java.base; // 导入 java 模块的所有基础公共类 // 可直接使用 List、ArrayList 等无需单独导入 void main() { ListString list new ArrayList(); }[#](#老版写法-2) 老版写法import java.util.List; // 显式导入单个类 import java.util.ArrayList; // 显式导入另一个类 public class Main { public static void main(String[] args) { ListString list new ArrayList(); System.out.println(list); } }[#](#新版优点-2) 新版优点减少冗余的导入语句提升模块化代码的可读性和编写效率尤其在依赖多模块时非常有用。1.4 **原始类型模式匹配预览特性**在 switch 和 instanceof 中直接匹配原始类型如 int、boolean 等。[#](#新版写法-3) 新版写法static void test(Object obj) { if (obj instanceof int i) { // 直接匹配 int 类型 System.out.println(Its an int: i); } }int value 10 ; switch (value) { case int i - IO.println(小整数: i); case float f - IO.println(浮点数: f); }[#](#老版写法-3) 老版写法static void test(Object obj) { if (obj instanceof Integer) { // 检查是否为 Integer 包装类型 int i (int) obj; // 显式拆箱 System.out.println(Its an int: i); } }目前模式匹配只能用于引用类型如果你想在 switch 中匹配基本类型只能用常量不能绑定变量。早期版本 instanceof 仅支持引用类型如 Integer、String需依赖装箱/拆箱Integer → int。[#](#新版优点-3) 新版优点统一原始类型与引用类型的模式匹配简化类型判断逻辑减少样板代码。[#](#_2-并发编程增强) 2.并发编程增强[#](#_2-1-作用域值-scoped-values) 2.1 **作用域值Scoped Values**允许在线程内和跨线程共享不可变数据旨在替代 ThreadLocal优化虚拟线程不可变信息的传递。ThreadLocal 使用场景在同一个请求内获取用户信息public class UserService { private static final ThreadLocalString USER_ID new ThreadLocal(); public void processRequest(String userId) { USER_ID.set(userId); // 写入 doWork(); USER_ID.remove(); // 问题必须手动清理容易忘记 } public void doWork() { String userId USER_ID.get(); // 读取 System.out.println(处理用户: userId); // 问题其他代码可以随意修改 USER_ID.set(被篡改的值); } }容易内存泄漏必须手动调用font stylecolor:rgb(31, 35, 40);background-color:rgba(129, 139, 152, 0.12);remove()/font可以随意修改数据可能导致不可预期的结果如果想让子线程也共享数据每个子线程都要复制一份数据。如果你使用的是 Java 21 的虚拟线程1000 个虚拟线程就要复制1000 次性能很差。font stylecolor:rgb(31, 35, 40);/fontInheritableThreadLocalString threadLocal new InheritableThreadLocal(); threadLocal.set(用户数据); for (int i 0; i 1000; i) { Thread.ofVirtual().start(() - { String data threadLocal.get(); // 每个线程都有自己的副本 }); }什么是 Scoped ValuesScoped Values 允许方法在线程内以及子线程间安全高效地共享不可变数据。和传统的 ThreadLocal 相比它不仅更安全而且在虚拟线程环境下的内存开销要小很多。Scoped Values 和 ThreadLocal 的写法很像font stylecolor:rgb(31, 35, 40);/fontimport static java.lang.ScopedValue.where; public class UserService { private static final ScopedValueString USER_ID ScopedValue.newInstance(); public void processRequest(String userId) { where(USER_ID, userId) // 写入并绑定作用域 .run(this::doWork); // 自动清理无需 remove() } public void doWork() { String userId USER_ID.get(); // 读取 System.out.println(处理用户: userId); } }用font stylecolor:rgb(31, 35, 40);background-color:rgba(129, 139, 152, 0.12);where().run()/font自动管理作用域出了作用域就自动清理更安全。而且作用域一旦绑定值就不能被修改避免意外的状态变更。font stylecolor:rgb(31, 35, 40);/font使用方式1支持返回值除了font stylecolor:rgb(31, 35, 40);background-color:rgba(129, 139, 152, 0.12);run()/font方法还可以使用font stylecolor:rgb(31, 35, 40);background-color:rgba(129, 139, 152, 0.12);call()/font方法来处理有返回值的场景public String processWithResult(String input) { return where(CONTEXT, input) .call(() - { String processed doSomeWork(); return 结果: processed; }); }2嵌套作用域支持在已有作用域内建立新的嵌套作用域void outerMethod() { where(X, hello).run(() - { System.out.println(X.get()); // 输出 hello where(X, goodbye).run(() - { System.out.println(X.get()); // 输出 goodbye }); System.out.println(X.get()); // 输出 hello }); }3多值绑定可以在一个调用中绑定多个 Scoped Values或者直接用类封装多个值where(USER_ID, userId) .where(REQUEST_ID, requestId) .where(TENANT_ID, tenantId) .run(() - { processRequest(); });4和结构化并发配合Scoped Values 和 Java 结构化并发 API 可以打个配合子线程自动继承父线程的作用域值void handleRequest() { where(USER_ID, getCurrentUserId()) .run(() - { try (var scope StructuredTaskScope.open()) { var userTask scope.fork(() - loadUser()); // 子线程可以访问 USER_ID var ordersTask scope.fork(() - loadOrders()); // 子线程可以访问 USER_ID try { scope.join(); } catch (InterruptedException e) { throw new RuntimeException(e); } IO.println(userTask.get()); IO.println(ordersTask.get()); } }); }如果要在线程中共享不可变数据、尤其是使用了虚拟线程的场景建议使用 Scoped Values但如果线程中共享的数据可能需要更新那么还是使用 ThreadLocal要根据实际场景选择[#](#新版优点-4) 新版优不可变性保证线程安全内存占用比 ThreadLocal 低约 40%生命周期自动绑定无内存泄漏风险尤其适合虚拟线程场景。[#](#_2-2-结构化并发-预览特性) 2.2 **结构化并发预览特性**将运行在不同线程中的相关任务视为单个工作单元来管理简化错误处理和取消操作。[#](#新版写法-5) 新版写法try (var scope StructuredTaskScope.Stringopen()) { SubtaskString userTask scope.fork(() - fetchUser()); SubtaskString orderTask scope.fork(() - fetchOrder()); scope.join(); // 等待所有子任务完成或任一失败 if (userTask.state() Subtask.State.SUCCESS) { return new Response(userTask.get(), orderTask.get()); } else { throw new RuntimeException(Subtask failed, userTask.exception()); } }结构化并发就是来解决并发编程中线程泄露和资源管理问题的自动清理任一任务失败其他任务自动取消异常传播主线程被中断子任务也会取消资源管理可以配合 try-with-resources 保证资源释放[#](#新版优点-5) 新版优点提高并发代码的可靠性和可观察性尤其利于错误传播和任务取消。[#](#_3-性能优化) 3.性能优化[#](#_3-1-紧凑对象头) 3.1 紧凑对象头说明将对象头从 128 位压缩至 64 位减少小对象的内存占用。启用添加 JVM 参数 -XX:UseCompactObjectHeaders。[#](#新版优点-6) 新版优点显著减少内存占用小型对象最多可节省 33%提升执行效率CPU 时间减少GC 频率降低。测试显示堆占用减少 22%CPU 时间减少 8%GC 次数减少 15%。无需修改代码即可受益对微服务、云环境等内存受限场景尤其有利。[#](#_3-2-shenandoah-分代垃圾回收器) 3.2 Shenandoah 分代垃圾回收器说明Shenandoah GC 的分代模式正式成为生产就绪特性。启用-XX:UseShenandoahGC -XX:ShenandoahGCModegenerational。[#](#新版优点-7) 新版优点针对新生代和老年代采用差异化回收策略停顿时间降低高达 40%适合高吞吐应用。[#](#_4-安全增强) 4.安全增强引入一些列加密工具类实现信息加密例如引入基于晶格密码的 ML-KEM密钥封装和 ML-DSA数字签名算法实现代码如下KeyPairGenerator kpg KeyPairGenerator.getInstance(ML-DSA); KeyPair kp kpg.generateKeyPair(); Signature sig Signature.getInstance(ML-DSA); sig.initSign(kp.getPrivate()); sig.update(message); byte[] signature sig.sign(); // 验证签名 sig.initVerify(kp.getPublic()); sig.update(message); boolean verified sig.verify(signature);font stylecolor:rgb(44, 62, 80);/font其他特性【了解】移除 32 位 x86 支持Java 25 正式移除了对 32 位 x86 架构的支持。简单来说就是32 位系统现在用不了 Java 25 了。【了解】JFR 性能分析增强JFRJava Flight Recorder飞行记录器是 JDK 内置的低开销性能监控工具可以记录程序运行时的详细数据。它在这个版本获得了几个重要增强包括更精确地测量 CPU 使用情况、通过协作式采样保证了 JVM 安全性、可以更安全地在生产环境开启分析等。【了解】Vector API第 10 次孵化Vector API 继续孵化主要改进更好的数学函数支持现在通过 FFM API 调用本地数学库提高可维护性Float16 支持增强在支持的 CPU 上可以自动向量化 16 位浮点运算VectorShuffle 增强支持与 MemorySegment 交互