JDK 25 是 LTS(长期支持版),至此为止,有 JDK8、JDK11、JDK17、JDK21 和 JDK 25 这四个长期支持版了。
JDK 25 共有 18 个新特性,这篇文章会挑选其中较为重要的一些新特性进行详细介绍
JDK25作为第三次preview
在Java的模式匹配框架instanceof
和switch
中直接支持原始类型(如int
、boolean
),使这种表达式更加直接,减少样板代码,例如:
static void test(Object obj) {
if (obj instanceof int i) {
System.out.println("It's an int: " + i);
}
}
该特性第一次预览是由 JEP 476(JDK 23 )提出,随后在 JEP 494 (JDK 24)中进行了完善,JDK 25 顺利转正。
支持import module
语句声明模块依赖,替代部分包导入,提升代码可读性和工具链兼容性,例如:
import module java.base; // 包含了import java.io.*; import java.util.*;
import module java.base; // exports java.util, which has a public Date class
import module java.sql; // exports java.sql, which has a public Date class
import java.sql.Date; // resolve the ambiguity of the simple name Date!
...
Date d = ... // Ok! Date is resolved to java.sql.Date
...
该特性第一次预览是由 JEP 445(JDK 21 )提出,随后经过了 JDK 22 、JDK 23 和 JDK 24 的改进和完善,最终在 JDK 25 顺利转正。
简化程序入口,支持类级别的void main()
方法,无需public static
修饰,允许我们在没有类声明的情况下编写脚本或演示:
void main() {
System.out.println("Hello Java 25!");
}
这是为了降低 Java 的学习门槛和提升编写小型程序、脚本的效率而迈出的一大步。初学者不再需要理解 public static void main(String[] args)
这一长串复杂的声明。对于快速原型验证和脚本编写,这也使得 Java 成为一个更有吸引力的选择。
该特性第一次预览是由 JEP 447(JDK 22)提出,随后在 JEP 482 (JDK 23)和 JEP 492(JDK 24)经历了预览,JDK 25 顺利转正。
Java 要求在构造函数中,super(...)
或 this(...)
调用必须作为第一条语句出现。这意味着我们无法在调用父类构造函数之前在子类构造函数中直接初始化字段。
灵活的构造函数体解决了这一问题,它允许在构造函数体内,在调用 super(..)
或 this(..)
之前编写语句,这些语句可以初始化字段,但不能引用正在构造的实例。这样可以防止在父类构造函数中调用子类方法时,子类的字段未被正确初始化,增强了类构造的可靠性。
class User {
private final String id;
User(String rawId) {
super();
this.id = validateAndFormat(rawId);
}
}
该特性第一次预览是由 JEP 450 (JDK 24 )提出,JDK 25 就顺利转正了。
减少了64位体系结构上的对象头大小,此更改通过在对象头中使用紧凑的同步和标识数据布局,减少了Java对象的内存占用。
紧凑对象头并没有成为 JVM 默认的对象头布局方式,需通过显式配置启用:
$ java -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders ...
;-XX:+UseCompactObjectHeaders
即可启用。JDK 19 引入了结构化并发,一种多线程编程方法,目的是为了通过结构化并发 API 来简化多线程编程,并不是为了取代java.util.concurrent
,目前处于孵化器阶段。
结构化并发将将子任务视为逻辑单元,父任务取消时自动终止子线程,简化错误处理和取消操作,防止资源泄漏,提升高并发可靠性。
结构化并发的基本 API 是StructuredTaskScope
,它支持将任务拆分为多个并发子任务,在它们自己的线程中执行,并且子任务必须在主任务继续之前完成。
StructuredTaskScope
的基本用法如下:
try (var scope = new StructuredTaskScope
结构化并发非常适合虚拟线程,虚拟线程是 JDK 实现的轻量级线程。许多虚拟线程共享同一个操作系统线程,从而允许非常多的虚拟线程。
Shenandoah GC 在 JDK12 中成为正式可生产使用的 GC,默认关闭,通过 -XX:+UseShenandoahGC
启用。
Redhat 主导开发的 Pauseless GC 实现,主要目标是 99.9% 的暂停小于 10ms,暂停与堆大小无关等
传统的 Shenandoah 对整个堆进行并发标记和整理,虽然暂停时间极短,但在处理年轻代对象时效率不如分代 GC。引入分代后,Shenandoah 可以更频繁、更高效地回收年轻代中的大量“朝生夕死”的对象,使其在保持极低暂停时间的同时,拥有了更高的吞吐量和更低的 CPU 开销。
Shenandoah GC 需要通过命令启用:
-XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=generational
-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational
即可启用。替代ThreadLocal
,支持线程间安全共享不可变数据,简化生命周期管理。
JDK19的JEP 428: Structured Concurrency (Incubator)作为第一次incubator
JDK20的JEP 437: Structured Concurrency (Second Incubator)作为第二次incubator
JDK21的JEP 453: Structured Concurrency (Preview)作为首次preview
JDK22的JEP 462: Structured Concurrency (Second Preview)作为第二次preview
JDK23的JEP 480: Structured Concurrency (Third Preview)作为第三次preview
JDK24的JEP 487: Scoped Values (Fourth Preview)作为第四次preview,与JDK23不同的是callWhere以及runWhere方法从ScopedValue类中移除,可以使用ScopedValue.where()再链式调用run(Runnable)或者call(Callable)
JDK25作为第五次preview,有个改动就是 ScopedValue.orElse 方法不再接受null作为参数
class Framework {
private static final ScopedValue CONTEXT
= ScopedValue.newInstance(); // (1)
void serve(Request request, Response response) {
var context = createContext(request);
where(CONTEXT, context) // (2)
.run(() -> Application.handle(request, response));
}
public PersistedObject readKey(String key) {
var context = CONTEXT.get(); // (3)
var db = getDBConnection(context);
db.readKey(key);
}
}
作用域值通过其“写入时复制”(copy-on-write)的特性,保证了数据在线程间的隔离与安全,同时性能极高,占用内存也极低。这个特性将成为未来 Java 并发编程的标准实践。
标准化类文件解析与生成接口,取代ASM等第三方库。
完全删除32位x86平台的支持,包括:
HotSpot
虚拟机中的 x86-32 后端);
本文来自在线网站:seven的菜鸟成长之路,作者:seven,转载请注明原文链接:www.seven97.top
参与评论
手机查看
返回顶部