JDK 25 正式发布,长期支持
<p>JDK 25 是 LTS(长期支持版),至此为止,有 JDK8、JDK11、JDK17、JDK21 和 JDK 25 这四个长期支持版了。</p><p>JDK 25 共有 18 个新特性,这篇文章会挑选其中较为重要的一些新特性进行详细介绍</p>
<h2 id="语言特性">语言特性</h2>
<h3 id="基本类型模式匹配jep-507">基本类型模式匹配(JEP 507)</h3>
<p>JDK25作为第三次preview</p>
<p>在Java的模式匹配框架<code>instanceof</code>和<code>switch</code>中直接支持原始类型(如<code>int</code>、<code>boolean</code>),使这种表达式更加直接,减少样板代码,例如:</p>
<pre><code class="language-java">static void test(Object obj) {
if (obj instanceof int i) {
System.out.println("It's an int: " + i);
}
}
</code></pre>
<h3 id="模块导入声明jep-511">模块导入声明(JEP 511)</h3>
<p>该特性第一次预览是由 JEP 476(JDK 23 )提出,随后在 JEP 494 (JDK 24)中进行了完善,JDK 25 顺利转正。</p>
<p>支持<code>import module</code>语句声明模块依赖,替代部分包导入,提升代码可读性和工具链兼容性,例如:</p>
<pre><code class="language-java">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
...
</code></pre>
<h3 id="压缩源文件与实例主方法jep-512">压缩源文件与实例主方法(JEP 512)</h3>
<p>该特性第一次预览是由 JEP 445(JDK 21 )提出,随后经过了 JDK 22 、JDK 23 和 JDK 24 的改进和完善,最终在 JDK 25 顺利转正。</p>
<p>简化程序入口,支持类级别的<code>void main()</code>方法,无需<code>public static</code>修饰,允许我们在没有类声明的情况下编写脚本或演示:</p>
<pre><code class="language-java">void main() {
System.out.println("Hello Java 25!");
}
</code></pre>
<p>这是为了降低 Java 的学习门槛和提升编写小型程序、脚本的效率而迈出的一大步。初学者不再需要理解 <code>public static void main(String[] args)</code> 这一长串复杂的声明。对于快速原型验证和脚本编写,这也使得 Java 成为一个更有吸引力的选择。</p>
<h3 id="灵活的构造函数体jep-513">灵活的构造函数体(JEP 513)</h3>
<p>该特性第一次预览是由 JEP 447(JDK 22)提出,随后在 JEP 482 (JDK 23)和 JEP 492(JDK 24)经历了预览,JDK 25 顺利转正。</p>
<p>Java 要求在构造函数中,<code>super(...)</code> 或 <code>this(...)</code> 调用必须作为第一条语句出现。这意味着我们无法在调用父类构造函数之前在子类构造函数中直接初始化字段。</p>
<p>灵活的构造函数体解决了这一问题,它允许在构造函数体内,在调用 <code>super(..)</code> 或 <code>this(..)</code> 之前编写语句,这些语句可以初始化字段,但不能引用正在构造的实例。这样可以防止在父类构造函数中调用子类方法时,子类的字段未被正确初始化,增强了类构造的可靠性。</p>
<pre><code class="language-java"> class User {
private final String id;
User(String rawId) {
super();
this.id = validateAndFormat(rawId);
}
}
</code></pre>
<h2 id="性能优化">性能优化</h2>
<h3 id="压缩对象头jep-519">压缩对象头(JEP 519)</h3>
<p>该特性第一次预览是由 JEP 450 (JDK 24 )提出,JDK 25 就顺利转正了。</p>
<p>减少了64位体系结构上的对象头大小,此更改通过在对象头中使用紧凑的同步和标识数据布局,减少了Java对象的内存占用。</p>
<p>紧凑对象头并没有成为 JVM 默认的对象头布局方式,需通过显式配置启用:</p>
<ul>
<li>JDK 24 需通过命令行参数组合启用:<code>$ java -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders ...</code> ;</li>
<li>JDK 25 之后仅需 <code>-XX:+UseCompactObjectHeaders</code> 即可启用。</li>
</ul>
<h3 id="结构化并发jep505-第五次预览">结构化并发(JEP505 第五次预览)</h3>
<p>JDK 19 引入了结构化并发,一种多线程编程方法,目的是为了通过结构化并发 API 来简化多线程编程,并不是为了取代<code>java.util.concurrent</code>,目前处于孵化器阶段。</p>
<p>结构化并发将将子任务视为逻辑单元,父任务取消时自动终止子线程,简化错误处理和取消操作,防止资源泄漏,提升高并发可靠性。</p>
<p>结构化并发的基本 API 是<code>StructuredTaskScope</code>,它支持将任务拆分为多个并发子任务,在它们自己的线程中执行,并且子任务必须在主任务继续之前完成。</p>
<p><code>StructuredTaskScope</code> 的基本用法如下:</p>
<pre><code class="language-java">try (var scope = new StructuredTaskScope<Object>()) {
// 使用fork方法派生线程来执行子任务
Future<Integer> future1 = scope.fork(task1);
Future<String> future2 = scope.fork(task2);
// 等待线程完成
scope.join();
// 结果的处理可能包括处理或重新抛出异常
... process results/exceptions ...
} // close
</code></pre>
<p>结构化并发非常适合虚拟线程,虚拟线程是 JDK 实现的轻量级线程。许多虚拟线程共享同一个操作系统线程,从而允许非常多的虚拟线程。</p>
<h3 id="分代-shenandoah-gc">分代 Shenandoah GC</h3>
<p>Shenandoah GC 在 JDK12 中成为正式可生产使用的 GC,默认关闭,通过 <code>-XX:+UseShenandoahGC</code> 启用。</p>
<p>Redhat 主导开发的 Pauseless GC 实现,主要目标是 99.9% 的暂停小于 10ms,暂停与堆大小无关等</p>
<p>传统的 Shenandoah 对整个堆进行并发标记和整理,虽然暂停时间极短,但在处理年轻代对象时效率不如分代 GC。引入分代后,Shenandoah 可以更频繁、更高效地回收年轻代中的大量“朝生夕死”的对象,使其在保持极低暂停时间的同时,拥有了更高的吞吐量和更低的 CPU 开销。</p>
<p>Shenandoah GC 需要通过命令启用:</p>
<ul>
<li>JDK 24 需通过命令行参数组合启用:<code>-XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=generational</code></li>
<li>JDK 25 之后仅需 <code>-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational</code> 即可启用。</li>
</ul>
<h2 id="安全性增强">安全性增强</h2>
<h3 id="作用域值scopedvalue">作用域值(ScopedValue)</h3>
<p>替代<code>ThreadLocal</code>,支持线程间安全共享不可变数据,简化生命周期管理。</p>
<blockquote>
<p>JDK19的JEP 428: Structured Concurrency (Incubator)作为第一次incubator<br>
JDK20的JEP 437: Structured Concurrency (Second Incubator)作为第二次incubator<br>
JDK21的JEP 453: Structured Concurrency (Preview)作为首次preview<br>
JDK22的JEP 462: Structured Concurrency (Second Preview)作为第二次preview<br>
JDK23的JEP 480: Structured Concurrency (Third Preview)作为第三次preview<br>
JDK24的JEP 487: Scoped Values (Fourth Preview)作为第四次preview,与JDK23不同的是callWhere以及runWhere方法从ScopedValue类中移除,可以使用ScopedValue.where()再链式调用run(Runnable)或者call(Callable)</p>
</blockquote>
<p>JDK25作为第五次preview,有个改动就是 ScopedValue.orElse 方法不再接受null作为参数</p>
<pre><code class="language-java">class Framework {
private static final ScopedValue<FrameworkContext> 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);
}
}
</code></pre>
<p>作用域值通过其“写入时复制”(copy-on-write)的特性,保证了数据在线程间的隔离与安全,同时性能极高,占用内存也极低。这个特性将成为未来 Java 并发编程的标准实践。</p>
<h2 id="体验优化">体验优化</h2>
<h3 id="飞行记录仪jfr升级">飞行记录仪(JFR)升级</h3>
<ul>
<li>增强Linux系统CPU时间分析,精准定位性能瓶颈。</li>
<li>协作式采样支持安全线程栈检查,优化Java程序性能。</li>
</ul>
<h3 id="类文件-api-转正">类文件 API 转正</h3>
<p>标准化类文件解析与生成接口,取代ASM等第三方库。</p>
<h3 id="垃圾回收器改进">垃圾回收器改进</h3>
<ul>
<li>Shenandoah分代回收器正式转正,优化内存管理效率。</li>
<li>G1垃圾回收器增强后期屏障,减少停顿时间。</li>
</ul>
<h3 id="弃用陈旧特性">弃用陈旧特性</h3>
<p>完全删除32位x86平台的支持,包括:</p>
<ul>
<li>删除相关源代码(如<code>HotSpot</code>虚拟机中的 x86-32 后端);</li>
<li>移除构建配置、测试基础设施中与 x86-32 相关的内容;</li>
<li>只保留对x86-64(64 位)平台的支持,推动现代化硬件迁移。</li>
</ul>
</div>
<div id="MySignature" role="contentinfo">
<p>本文来自在线网站:seven的菜鸟成长之路,作者:seven,转载请注明原文链接:www.seven97.top</p><br><br>
来源:https://www.cnblogs.com/sevencoding/p/19102955
頁:
[1]