当前位置: 首页 > news >正文

Java25 新特性介绍

哈喽大家好,我是晓宜

java25最近新发布了,这个新的长期支持版本(LTS)计划于 2025 年 9 月推出,在 Java 语言、标准库、API 和运行时等方面带来全面增强,我们来看下有哪些新特性值得关注

正式版功能

作用域值(JEP 506 – 正式版)

JEP 506 提供了轻量级、不可变、线程安全的 ThreadLocal 替代方案。专为与虚拟线程协同工作设计:

import java.lang.ScopedValue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ScopedUserExample {static final ScopedValue<String> USER = ScopedValue.newInstance();public static void main(String[] args) {try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {executor.submit(() -> ScopedValue.where(USER, "Alice").run(() -> {System.out.println("Thread: " + Thread.currentThread());System.out.println("User: " + USER.get());}));executor.submit(() -> ScopedValue.where(USER, "Bob").run(() -> {System.out.println("Thread: " + Thread.currentThread());System.out.println("User: " + USER.get());}));// 可选延迟确保输出在主线程退出前显示Thread.sleep(200);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}

作用域值设计用于以安全、高性能、不可变的方式在调用链中传递上下文。它们特别适合虚拟线程和结构化并发,通过避免内存泄漏和同步开销,提供了比 ThreadLocal 更高效的替代方案。

⚠️ 注意:当作用域值与虚拟线程一起使用时,访问作用域值的逻辑必须包装在 ScopedValue.where(...).run(...) 作用域内。仅将任务提交到作用域内的执行器是不够的,任务本身必须在作用域内创建以保留绑定。

密钥派生函数 API(JEP 510 – 正式版)

Java 25 引入了基于密码的密钥派生函数(如 PBKDF2 和 scrypt)的标准 API:

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;public class KeyDerivationExample {public static void main(String[] args) throws Exception {char[] password = "hunter2".toCharArray();byte[] salt = "somesalt".getBytes();PBEKeySpec spec = new PBEKeySpec(password, salt, 65536, 256);SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");SecretKey key = factory.generateSecret(spec);System.out.println("Derived key format: " + key.getFormat());}
}

JEP 510 标准化了从用户密码派生加密密钥的广泛使用加密原语的访问,减少了对第三方库的依赖,实现了开箱即用的安全实现。

紧凑源文件(JEP 512)与实例主方法

现在 Java 支持顶级实例 main 方法和无类的紧凑文件。这意味着以下声明是有效的:

void main() {System.out.println("Hello from Java 25!");
}

JEP 512 基于 Java 21 引入的简化启动器,允许我们编写无需类声明的快速脚本或演示。

灵活的构造函数体(JEP 513 – 正式版)

灵活构造函数体(JEP 513)允许在构造函数调用之前添加语句

class Person {final int age;Person(int age) {this.age = age;}
}class Employee extends Person {final String name;Employee(String name, int age) {if (age < 18 || age > 67)throw new IllegalArgumentException("Age must be between 18 and 67");super(age); // Java 25 中 super() 不再必须是第一条语句this.name = name;}public static void main(String[] args) {var emp = new Employee("Alice", 35);System.out.println("Person age set: " + emp.age);}
}

在 JEP 513 之前,Java 构造函数要求将 super(...) 或 this(...) 作为第一条语句,这常迫使我们重复验证或初始化逻辑,或将其推入静态辅助方法。JEP 513 允许在构造函数调用前包含代码,使参数验证或共享设置能在一个地方干净地完成,提升了可读性、快速失败行为和对象完整性,同时不破坏 Java 的构造规则

提前命令行人机工程学(JEP 514 – 正式版)

JEP 514 是 Project Leyden 的一部分,引入了新的 JVM 命令行标志(\-XX:AOTCacheOutput=<file>),禁用动态特性(如类加载和反射)以评估应用在受限运行时环境中的性能表现。这些标志帮助我们识别阻碍静态映像生成或未来提前 (AOT) 编译的问题代码路径。

虽然 Java 25 尚未提供内置 AOT 编译器,但此 JEP 通过支持早期实验奠定了基础。它支持交付具有可预测启动性能和低内存占用的静态 Java 应用的长期目标。

提前方法分析(JEP 515 – 正式版)

JEP 515 引入了方法级分析,记录调用方法及其频率等执行特征。这些数据可保存并重用,为未来优化(如提前编译)提供信息。虽然 Java 25 尚未包含 AOT 编译器,但此 JEP 通过支持分析引导优化,为未来版本改进启动性能奠定了关键基础。

JFR 协作采样(JEP 518 – 正式版)

JEP 518 允许应用向 Java Flight Recorder 建议安全采样点。协作采样通过将采样与应用定义的安全点对齐来减少开销,在最小化对性能敏感代码干扰的同时提高准确性。

紧凑对象头(JEP 519 – 正式版)

JEP 519 减少了 64 位架构上的对象头大小。此更改通过在对象头中使用紧凑布局存储同步和身份数据,缩小了 Java 对象的内存占用。这对大堆和微服务环境特别有益。

JFR 方法计时与跟踪(JEP 520 – 正式版)

JEP 520 通过记录线程上所有方法调用的计时数据(不仅是采样方法)来增强可观测性。这支持精确重建时间间隔内的方法调用堆栈和持续时间,帮助我们更彻底地分析执行流和并发行为。它通过提供更丰富的确定性跟踪数据(而非概率采样)补充了现有分析功能。

分代式 Shenandoah(JEP 521 – 正式版)

JEP 521 为 Shenandoah 垃圾收集器添加了分代支持。分代 GC 通过单独优化新生代收集与长期存活对象,提高了吞吐量和暂停时间性能。它使 Shenandoah 在效率上与 G1 和 ZGC 等收集器保持一致。

移除 32 位 x86 端口(JEP 503 – 正式版)

JEP 503 从 OpenJDK 中移除了对传统 32 位 x86 架构的支持。此 JEP 消除了对相关性日益下降平台的维护开销。64 位 x86 和 ARM64 端口仍完全支持。

孵化器和前瞻阶段功能

模式匹配支持原始类型(JEP 507 – 第三预览)

现在模式匹配可以在 switch 和 instanceof 语句中处理原始类型。例如:

static void test(Object obj) {if (obj instanceof int i) {System.out.println("It's an int: " + i);}
}

JEP 507 将原始类型引入 Java 的模式匹配框架,使这类表达式更直观,减少样板代码。这是统一语言类型模式更广泛努力的一部分。

模块导入声明(JEP 511 – 预览)

JEP 511 引入模块导入声明,允许我们通过 import 语句声明模块依赖,提升模块可读性。传统上,模块依赖只能在 module-info.java 描述符中通过 requires 指令声明。JEP 511 引入了一种在 Java 文件顶部使用 import module 语句声明模块依赖的方式,类似于传统 import 语句。这增强了清晰度,使工具能在开发时更准确地推断依赖。例如:

import module java.base; 
//...public class Main {public static void main(String[] args) {Date d = new Date();System.out.println("Resolved Date: " + d);}
}

⚠️ 但需注意模糊引用问题。看这个示例:

import module java.base;      // 导出 java.util,包含 java.util.Date
import module java.sql;       // 导出 java.sql,也包含 java.sql.Datepublic class Main {public static void main(String[] args) {Date d = Date.valueOf("2025-06-15");System.out.println("Resolved Date: " + d);}
}

编译时会报错:

error: reference to Date is ambiguousDate d = Date.valueOf("2025-06-15");^both class java.sql.Date in java.sql and class java.util.Date in java.util matcherror: reference to Date is ambiguous

解决方案是添加具体类的导入:

import module java.base;
import module java.sql;import java.sql.Date;public class Main {public static void main(String[] args) {Date d = Date.valueOf("2025-06-15");System.out.println("Resolved Date: " + d);}
}

✅ 此特性还允许将星号导入替换为模块导入:

// 这些导入可以合并:
import javax.xml.*; 
import javax.xml.parsers.*; 
import javax.xml.stream.*;

改为:

import module java.xml;

虽然不建议滥用星号导入和模块导入,但这确实使依赖声明更简洁。

结构化并发(JEP 505 – 第五预览)

JEP 505 旨在通过将相关线程作为具有适当生命周期管理的单一单元来简化并发。第五预览版通过用单个静态工厂方法 StructuredTaskScope.open() 替换构造函数和独立策略方法来优化 API。这种方法提高了定义自定义连接和错误处理行为的一致性和灵活性。下面使用新语法:

import java.util.concurrent.StructuredTaskScope;public class StructuredExample {static String fetchUser() {try {Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}return "Alice";}static String fetchOrder() {try {Thread.sleep(150);} catch (InterruptedException e) {Thread.currentThread().interrupt();}return "Order#42";}public static void main(String[] args) throws Exception {try (var scope = StructuredTaskScope.<String>open()) {var userTask = scope.fork(() -> fetchUser());var orderTask = scope.fork(() -> fetchOrder());scope.join();System.out.println(userTask.get() + " - " + orderTask.get());}}
}

结构化并发帮助我们管理逻辑相关的多个并发任务。它保证子线程作为整体完成或取消,提高了多线程应用的可靠性和可读性。

稳定值 API(JEP 502 – 预览)

稳定值 API(JEP 502)将类似 Optional 的语义扩展到上下文稳定的不可变值:

import java.lang.StableValue;public class StableExample {public static void main(String[] args) {// 创建未设置的稳定值var greeting = StableValue.<String>of();String message = greeting.orElseSet(() -> "Hello from StableValue!");System.out.println(message);}
}

稳定值提供了一种安全跨线程或计算共享不可变、上下文稳定值的 API。它们在涉及缓存、惰性求值或稳定范围内一致读取的场景中特别有用,并与结构化并发良好集成。

加密对象的 PEM 编码(JEP 470 – 预览)

JEP 470 通过标准 API 添加了对 PEM 格式加密密钥和证书的读写支持。新 API 抽象了这些操作,使其变得简单:

import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;public class PEMExample {public static void main(String[] args) {String pem = """-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgjDohS0RHP395oJxciVaeks9NKNY5m9V1IkBBwYsMGyxskrW5sapgi9qlGSYOma9kkko1xlBs17qG8TTg38faxgGJsLT2BAmdVFwuWdRtzq6ONn2YPHYj5s5pqx6vU5baz58/STQXNIhn21QoPjXgQCnjPp0OxnacWeRSnAIOmQIDAQAB-----END PUBLIC KEY-----""";try {String base64 = pem.replaceAll("-----.*-----", "").replaceAll("\\s", "");byte[] keyBytes = Base64.getDecoder().decode(base64);X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);KeyFactory factory = KeyFactory.getInstance("RSA");PublicKey key = factory.generatePublic(spec);System.out.println("Loaded key: " + key.getAlgorithm());} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {e.printStackTrace();}}
}

现在我们可以利用 Java 安全 API 直接处理 PEM 编码对象(如 X.509 证书和 RSA 密钥),无需第三方库或手动转换。这提高了与基于 OpenSSL 系统的互操作性,简化了安全通信。

向量 API(JEP 508 – 第十孵化器)

JEP 508 提供了一个 API,用于表达向量计算,这些计算能可靠编译为最优向量硬件指令:

import jdk.incubator.vector.*;public class VectorExample {public static void main(String[] args) {float[] left = {1f, 2f, 3f, 4f};float[] right = {5f, 6f, 7f, 8f};FloatVector a = FloatVector.fromArray(FloatVector.SPECIES_128, left, 0);FloatVector b = FloatVector.fromArray(FloatVector.SPECIES_128, right, 0);FloatVector c = a.add(b);float[] result = new float[FloatVector.SPECIES_128.length()];c.intoArray(result, 0);System.out.println("Vector result: " + java.util.Arrays.toString(result));}
}

要求:–enable-preview –add-modules jdk.incubator.vector

向量 API 支持可在现代 CPU 上高效执行的数据并行计算。它通过利用 SIMD 指令,使 Java 代码达到与手动调优的本机代码相当的性能,并继续通过孵化器阶段演进。

JFR CPU 时间分析(JEP 509 – 实验性)

JEP 509 为 Java Flight Recorder (JFR) 添加了基于 CPU 时间的分析支持。此特性使我们能记录和分析特定方法或线程花费的 CPU 时间,从而改进性能诊断,特别是在多线程和 I/O 密集型工作负载中。使用新的 JDK.CPULoad 和相关 JFR 事件进行自定义记录:

java-XX:StartFlightRecording=filename=cpu-time.jfr,duration=10s,settings=profile--enable-previewMyApp

然后在 JDK Mission Control 或 VisualVM 中分析 cpu-time.jfr 文件,观察方法和线程的 CPU 使用情况。

引用链接

Java 25 新特性详解 | Baeldung中文网

https://www.baeldung.com/java-25-features

刚刚 Java 25 炸裂发布!让 Java 再次伟大 - 程序员鱼皮 - 博客园

https://www.oracle.com/tw/news/announcement/oracle-releases-java-25-2025-09-16/

https://blog.csdn.net/weixin_43408952/article/details/124761324

http://www.dtcms.com/a/458160.html

相关文章:

  • 珠海做网站找哪家好在线网站推荐几个
  • 倍增:64位整除法
  • 钓鱼网站开发系列教程2013电子商务网站建设
  • Python协程详解:从并发编程基础到高性能服务器开发
  • 以太网数据包协议字段全解析(进阶补充篇)
  • 北京手机网站建设公司哪家好目前较好的crm系统
  • githup网站建设广州工程建设网站
  • 【C++实战(80)】解锁C++大数据处理密码:复盘、调优与实战突破
  • 做一网站需要多少钱博客社区类网站模板下载
  • 【Git】 远程操作 与 标签管理
  • 新品速递 | 亚信电子发布 AX58101 EtherCAT 子设备控制器
  • 山西手机版建站系统哪家好电信宽带360元一年
  • Spring Boot JSON匹配测试
  • 9.MySQL索引
  • Java--多线程基础知识(四)
  • 实现接口文档与测试脚本的实时同步
  • 用vis做的简单网站汉语言专业简历制作说明
  • 如何查看网站开发语言.net core 网站开发
  • 第5章:聊天记忆(Chat Memory)—让 AI 记住上下文
  • RAG创新方案支REFRAG
  • 高通收购Arduino,加速开发者获取领先的边缘计算与AI技术
  • 住房和城市建设厅网站wordpress本地网站怎么访问
  • mongo 适应场景
  • 沧浪企业建设网站价格win8导航网站模板
  • 实战篇:智能选配合理之轨——工业远心镜头选型终极攻略
  • 深入理解队列(Queue):从原理到实践的完整指南
  • 网站开发企业组织结构集团有限公司
  • 营销型网站建设 博客网页制作怎么做第二页
  • 网站前台功能傻瓜式网站
  • 初识Redis:理解其定位与适用场景