点击下方“JavaEdge”,选择“设为星标”
第一时间关注技术干货!
本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!
魔都架构师 | 全网30W技术追随者
大厂分布式系统/数据中台实战专家
主导交易系统百万级流量调优 & 车联网平台架构
AIGC应用开发先行者 | 区块链落地实践者
以技术驱动创新,我们的征途是改变世界!
实战干货:编程严选网
JDK 25 于 9 月 16 日正式发布,新版本提供了 18 个 JDK 增强建议,改进了 Java 语言,扩展了 AI 功能,帮助开发人员提高工作效率。
1 关键 JDK 增强建议(JEP) 1.1 语言特性 JEP 507: Primitive Types in Patterns, instanceof, and switch(模式匹配支持原始类型,第三次预览)
通过使 Java 更加统一且更具表达能力,帮助开发人员提高 Java 编程的工作效率。例如,开发人员可以消除他们在使用模式匹配、instanceof 和 switch 时遇到的基元类型的限制,从而增强模式匹配。该功能还在所有模式上下文中支持基元类型模式,并扩展 instanceof 和 switch,使其能够与所有基元类型一起使用。基元类型支持将尤其有益于开发人员构建集成了 AI 推理功能的应用。
增强的模式匹配,允许在instanceof和switch中使用原始类型。
switch (x.getYearlyFlights()) {
case 0, 1 -> standardRate();
case 2 -> issueDiscount();
case int i when i >= 100 -> issueGoldCard();
case int i when i > 2 && i < 100 -> issueSilverDiscount();
}
JEP 511: Module Import Declarations(模块导入声明)允许通过import module [模块名]一行代码导入整个模块的所有公共 API。
import module java.base;
String[] fruits = new String[] { "apple", "berry", "citrus" };Map m =
Stream.of(fruits).collect(Collectors.toMap(s -> s.toUpperCase().substring(0,1), Function.identity()));
如果多个模块中包含同名类(如Date),可通过显式导入来解决冲突:
import module java.base; // 导出 java.util,其中有 Date 类
import module java.sql; // 导出 java.sql,其中也有 Date 类
import java.sql.Date; // 解决 Date 的命名冲突Date d = ... // 解析为 java.sql.Date
开发人员可以轻松导入由模块导出的所有程序包,无需将导入代码放到模块中,从而提高工作效率。
简化了所有开发人员对模块化库的重用,让初学者能用第三方库和基本 Java 类而无需了解它们在程序包层次结构的位置。
开发人员还可在用模块所导出 API 的多个部分时,避免多项按需类型导入声明的噪声 — 这有益于综合使用 AI 推理和来自多个流行库的工作流的简单应用。
JEP 512: Compact Source Files and Instance Main Methods(简化源码文件与实例主方法)
“Paving the On-Ramp” 系列功能中的亮点之一。Compact Source Files and Instance Main Methods 在 JDK 25 中定稿。它简化了 Java 编写最小化程序的方式,将“Hello World”精简至三行,非常适合教学和脚本化用途。
void main() {
IO.printin("Hello, World!");
}
针对 Java 编程提供一个流畅的启动入口,帮助初学者以及系统和 IT 管理员更轻松地使用 Java 语言。这使学生无需了解针对大型程序而设计的语言特性,即可简单编写自己的第一个程序,随后在技能增长过程中不断完善代码。此外,非 Java 专家型系统和 IT 管理员可以简单编写小型程序,如脚本和命令行实用程序。
JEP 513: Flexible Constructor Bodies(灵活构造函数体)
在 JDK 25 中定稿,允许在构造函数调用super之前添加语句,如数据校验或设置默认值。
class Person {
int age;
void show() {
System.out.println("Age: " + this.age);
}
Person(..., int age) {
if (age < 0)
thrownew IllegalArgumentException(...);
this.age = age;
show();
}
}
class Employee extends Person {
String officeID;
@Override
void show() {
System.out.println("Age: " + this.age);
System.out.println("Office: " + this.officeID);
}
Employee(..., int age, String officeID) {
super(..., age);
if (age < 18 || age > 67)
thrownew IllegalArgumentException(...);
this.officeID = officeID;
}}
允许在显式调用构造函数前执行输入验证和安全计算,帮助开发人员提高代码安全性和可靠性。通过支持更自然的构造函数表达式和在字段对其他类代码(例如从一个超类构造函数调用的方法)可见前进行字段初始化,这可以提高代码安全性。此外,该特性还保留了现有的保证,即子类构造函数中的代码不会干扰超类实例化,能够提高可靠性。
1.2 库 JEP 505: Structured Concurrency(结构化并发,第五次预览)
将一组并发任务视为一个整体,简化异常处理与取消机制,提升稳定性和可观测性。
Response handle() throws InterruptedException {
try (var scope = StructuredTaskScope.open()) {
Subtask
user = scope.fork(() -> findUser());
Subtask
order = scope.fork(() -> fetchOrder());
scope.join();
return new Response(user.get(), order.get());
}
}
简化并发编程,帮助开发人员提高多线程代码的可维护性、可靠性和可观察性。通过将在不同线程中运行的相关任务组视为单个工作单元,结构化并发可以降低因取消和关闭而产生的常见风险,如线程泄漏和取消延迟。这尤其有益于通常需要并行运行多项任务的 AI 开发工作。
JEP 506: Scoped Values(作用域值)
Project Loom 的第二个重要功能。Scoped Values 提供了一种在特定作用域内可访问的不可变值。用途与ThreadLocal类似,用于提供上下文信息,但并不是ThreadLocal的替代品。
class Framework {
privatestaticfinal ScopedValue CONTEXT
= ScopedValue.newInstance();
void serve(Request request, Response response) {
var context = createContext(request);
where(CONTEXT, context)
.run(() -> Application.handle(request, response));
}
public PersistedObject readKey(String key) {
var context = CONTEXT.get();
var db = getDBConnection(context);
db.readKey(key);
}}
支持开发人员在线程内和线程之间共享不可变数据,从而提高项目的易用性、可理解性、性能和稳健性。这尤其有益于使用了 AI 平台、Web 框架和微服务的应用。此外,作用域值相比线程局部变量更易于推理,空间和时间成本更低,尤其是当与虚拟线程和结构化并发共同使用时。
JEP 502: Stable Values(稳定值,预览)
提供一种不可变的数据容器,类似常量,但比final更灵活。
class OrderController {
privatefinal StableValue logger = StableValue.of();
Logger getLogger() {
return logger.orElseSet(() -> Logger.create(OrderController.class));
}
void submitOrder(User user, List products) {
getLogger().info("order started");
...
getLogger().info("order submitted");
}}
为稳定值(保存不可变数据的对象)引入一个 API,帮助开发人员提高灵活性。由于 JVM 将稳定值视为常量,稳定值可实现与声明一个字段为 final 时同等的性能优化,同时提供更高的初始化时机灵活性。
JEP 508: Vector API(向量 API,第十次孵化)
允许以矢量方式编写计算代码,能在支持的 CPU 上编译为高效的矢量指令,性能优于标量计算。
通过一个 API,以一种在运行时可靠地编译为受支持 CPU 架构上的优化向量指令的方式来表达向量计算,帮助开发人员提高生产力。因此,开发人员可以实现优于等效标量计算的表现,这些计算通常用于 AI 推理和计算场景。
1.3 安全库 JEP 470: PEM Encodings of Cryptographic Objects(加密对象的 PEM 编码,预览)
提供了 API,用于将密钥、证书吊销列表等加密对象编码为常用的 PEM 格式。
通过一个新的用于对象编码的 API 帮助开发人员提高工作效率。该 API 不仅可对表示加密密钥、证书和证书吊销列表的对象编码,将其转化为已得到广泛应用且具有增强型隐私保护的邮件传输格式,还能从邮件传输格式解码回对象。这使开发人员可以更轻松地将 Java 应用和安全验证系统/设备(例如 Yubikey)集成在一起。
JEP 510: Key Derivation Function API(密钥派生函数 API)
在 JDK 24 中作为预览功能发布,如今在 JDK 25 中正式定稿。该 API 用于从一个密钥和其他数据中派生出新的密钥。以下示例展示了如何使用 KDF API:
// 创建指定算法的 KDF 对象
KDF hkdf = KDF.getInstance("HKDF-SHA256");
// 创建 ExtractExpand 参数规范
AlgorithmParameterSpec params =
HKDFParameterSpec.ofExtract()
.addIKM(initialKeyMaterial)
.addSalt(salt).thenExpand(info, 32);// 派生一个 32 字节的 AES 密钥
SecretKey key = hkdf.deriveKey("AES", params);
为密钥派生函数(使用密码学算法,从一个密钥和其他数据中派生出更多密钥)提供一个 API,帮助开发人员为新兴的量子计算环境做好准备。这为支持混合公钥加密提供了一个必要的构建块,有助于平稳过渡到量子安全加密。
1.4 性能更新 JEP 519: Compact Object Headers(紧凑对象头)
由 JDK 24 的实验特性转为正式功能。它可将对象头最小化,从而减少堆占用约 10–20%,并降低 GC 压力。
$ java -XX:+UseCompactObjectHeaders ...
在 64 位架构上将对象标头大小缩减至 64 位,帮助开发人员提高工作效率。这在降低实际工作负载上对象大小和内存占用的同时,还有助于提高部署密度和增强数据局部性。
JEP 514: Ahead-of-Time Command-Line Ergonomics(AOT 命令行优化)
简化了创建 AOT 缓存的流程。用户只需在运行时添加参数-XX:AOTCacheOutput=[缓存名],JVM 关闭时会自动生成缓存。
# 创建 AOT 缓存
$ java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App ...# 使用 AOT 缓存
$ java -XX:AOTCache=app.aot -cp app.jar com.example.App ...
更轻松地创建 Ahead-of-Time 缓存而无表达能力丢失,帮助开发人员提高工作效率。这将简化常见用例所需的命令,加快 Java 应用的启动速度。
JEP 515: Ahead-of-Time Method Profiling(AOT 方法分析)
允许将方法性能分析数据写入 AOT 缓存,从而加速应用程序启动时的 JIT 编译。
提高应用性能,帮助开发人员提高工作效率。通过将初始方法执行概要信息的收集从生产运行转移到训练运行,并通过 Ahead-of-Time 缓存传送概要信息,预热时间得以缩短。这使 JIT 编译器得以在应用启动时即时生成本机代码,而不是一直等到概要信息收集完毕。它还消除了对应用代码、库或框架的所有修改需求,消除了对应用执行的所有限制。
1.5 监视功能更新 JEP 509: JFR CPU-Time Profiling(JFR CPU 时间分析,实验性)
提供更精确的 CPU 时间分析,仅支持 Linux 系统。
$ java -XX:StartFlightRecording=jdk.CPUTimeSample=true,filename=profile.jfr ...
增强 JDK Flight Recorder (JFR) 来捕获更准确的 Linux 平台上 CPU 时间分析信息,识别待优化的程序元素,从而帮助开发人员提高工作效率和程序效率。
JEP 518: JFR Cooperative Sampling(JFR 协作采样)
通过改进线程堆栈采样机制,提高了 JFR 的稳定性。该变更不会影响现有行为,但能提升性能。
增强 JFR 在异步执行 Java 线程堆栈采样时的稳定性,帮助开发人员提高代码可靠性。这使 JFR 可以尽可能减少事件采样器中的安全点偏差,同时避免在安全点之外生成用于堆栈跟踪的风险性启发函数。它还允许创建样本请求来响应硬件事件,或在信号处理函数中创建样本请求,降低采样器线程的必要工作量。
JEP 520: JFR Method Timing & Tracing(JFR 方法计时与追踪)
该特性允许 JFR 追踪和计时方法执行,可通过命令行启用并分析结果。
方法追踪示例
$ java -XX:StartFlightRecording:
jdk.MethodTrace=org.springframework.data.jpa.repository.support.SimpleJpaRepository::findAll, \
filename=recording.jfr ...
$jfr view --cell-height 30 --width 200 jdk.MethodTrace recording.jfr
方法计时示例$ java -XX:StartFlightRecording=method-timing='org.springframework.data.jpa.repository.support.SimpleJpaRepository::findAll',dumponexit=true,filename=recording.jfr -jar target/spring-petclinic-3.5.0-SNAPSHOT.jar
$ jfr view method-timing recording.jfr
允许开发人员识别应用性能瓶颈、优化代码以及查找错误根因,帮助开发人员提高工作效率。这是通过使用字节码增强来扩展 JFR,使 JFR 得以进行方法时间分析和跟踪实现的。
JEP 521 - Generational Shenandoah(分代 Shenandoah)
分代 Shenandoah 在 JDK 25 中成为正式功能,可通过以下参数启用:
$ java -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational ...
编程严选网:http://www.javaedge.cn/ 专注分享AI时代下软件开发全场景最新最佳实践~
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.