Agentic AI、具身智能、强化学习框架、端侧大模型……来QCon上海站,感受AI的未来! 了解详情
写点什么

Java 25 为延迟不可变性引入了稳定值 API,并改进了应用程序启动

  • 2025-06-03
    北京
  • 本文字数:1629 字

    阅读完需:约 5 分钟

大小:467.59K时长:02:39
Java 25为延迟不可变性引入了稳定值API,并改进了应用程序启动

JEP 502,稳定值(预览版),在 JDK 25 中已移动到完成状态。这个 JEP 以前称为计算常量(预览版),它引入了计算常量的概念,被定义为最多初始化一次的不可变值持有者。新的 API 允许开发人员创建具有“延迟不可变性”的对象。这些对象可以在执行过程中的任何时候被初始化一次,然后保持不可变性,结合了 final 字段的性能优势和延迟初始化的灵活性。

 

稳定值 API 专门针对由复杂对象过早初始化而引起的应用程序启动性能问题。与必须在构造或类初始化期间初始化的 final 字段不同,稳定值可以按需初始化,同时还启用了 JVM 常量折叠优化。这些优化通常只适用于 final 字段。不过这仍然是一个预览功能

 

稳定值 API 围绕StableValue类展开,该类持有一个只能精确设置一次的数据值。主要的初始化方法orElseSet()可确保即使在并发访问 的情况下也能进行线程安全的至多一次初始化:

 

class OrderController {    private final StableValue<Logger> logger = StableValue.of();    Logger getLogger() {        return logger.orElseSet(() -> Logger.create(OrderController.class));    }}
复制代码

 

这种方法消除了与传统延迟初始化模式相关的常见陷阱。如果没有稳定的值,开发人员通常会使用带有 null 检查的可变字段,这会阻碍 JVM 优化,并会引入线程安全问题:

 

// 传统方法 - 失去了优化机会class OrderController {    private Logger logger = null; // 可变字段    Logger getLogger() {        if (logger == null) {            logger = Logger.create(OrderController.class);        }        return logger;    }}
复制代码

 

API 不能扩展了基本的稳定值,还包括稳定的供应商(supplier)和稳定的列表(list)。稳定的供应商允许在声明时指定初始化逻辑,同时延迟实际执行:

 

class DataService {    private final Supplier<DatabaseConnection> connection = StableValue.supplier(() -> new DatabaseConnection("jdbc:postgresql://localhost/db"));    void performQuery() {        DatabaseConnection db = connection.get(); // 数据库连接仅在首次访问时创建    }}
复制代码

 

稳定列表支持集合,其中各个元素在访问时单独初始化:

 

class ThreadPool {    private final List<WorkerThread> workers = StableValue.list(POOL_SIZE, index -> new WorkerThread(index));    WorkerThread getWorker(int index) {        return workers.get(index); // 仅在首次访问时创建工作线程    }}
复制代码

 

稳定值的关键优势在于 JVM 处理它们的方式。在底层,稳定值使用 JDK 内部的 @Stable 注解,它告诉 JVM,尽管存储在非 final 字段中,但值在初始更新后不会改变。这使得 final 字段可以使用相同的常量折叠优化。

 

稳定值使得从根本上重新考虑应用程序的初始化策略成为可能。现在,应用程序可以将昂贵组件的创建推迟到真正需要时,从而显著改善了启动时间:

 

class Application {    static final StableValue<OrderController> orders = StableValue.of();    static final StableValue<UserService> users = StableValue.of();    public static OrderController getOrderController() {        return orders.orElseSet(OrderController::new);    }}
复制代码

 

这种模式允许应用程序立即启动,并根据应用程序的执行路径需要按需初始化组件。这种方法特别适用于具有大量组件的大型企业应用程序,其中许多组件在典型的执行过程中可能不会被使用。

 

作为一个预览 API,稳定值需要在编译和运行时显式启用:

 

javac --release 25 --enable-preview MyApplication.javajava --enable-preview MyApplication
复制代码

 

预览状态允许开发团队在最终确定 API 设计和实现之前,从 Java 社区收集反馈。

 

Java 25 中的稳定值 API 为长期存在的初始化挑战提供了一个引人注目的解决方案,它为开发人员提供了一个工具,将不可变字段的安全和性能与延迟初始化的灵活性结合了起来。

 

原文链接:

https://www.infoq.com/news/2025/06/java25-stable-values-api-startup/

2025-06-03 10:045430

评论

发布
暂无评论

架构师训练营第四周总结

James-Pang

极客大学架构师训练营

架构师训练营第四章作业

吴吴

第四周-作业1

seng man

互联网面临的挑战

师哥

架构师训练营第四周学习总结

Bruce Xiong

架构师训练营第四章总结

吴吴

架构师训练营第四周总结

sunnywhy

第四周作业

晨光

04-作业01

孙强

高流量秒杀系统的优化思路

铁血杰克

大型互联网站技术猜想

Dawn

极客大学架构师训练营

redis设计与实现(1)redis数据结构

程序员老王

redis

架构师训练营第四周作业

James-Pang

极客大学架构师训练营

大型互联网系统会面对怎样的一些挑战

Acker飏

第四周总结

晨光

04-02学习总结

孙强

第四周学习总结

铁血杰克

大型互联网系统应用了哪些技术

elfkingw

极客大学架构师训练营

不会用这个远控工具 怎么好意思说你会远程运维?

InfoQ_21c8aba5317f

远控工具

架构师训练营 - 学习总结 第 4 周

水边

极客大学架构师训练营

架构模式:可复用的架构问题解决方案

Skye

架构模式 极客大学架构师训练营

【架构训练 Week04 作业】

Rex

作业:一个典型的大型互联网架构演进采用的技术

蒜泥精英

第四周作业

魔曦

极客大学架构师训练营

永中云转换助力教育行业文档在线预览更高效

InfoQ_21c8aba5317f

行业资讯 永中

计算机操作系统基础(八)---存储管理之内存分配与回收

书旅

php laravel 线程 操作系统 进程

第四周作业一

Dark

案例分享

互联网系统架构的演进-笔记心得

蒜泥精英

Week04总结

熊威

使用图解的方式来解决链表的算法问题

jerry.mei

Java 算法 链表 ARTS 打卡计划 js

ARTS 03 - 使用图解的方式来解决链表的算法问题

jerry.mei

算法 大前端 练习 ARTS 打卡计划 ES6

Java 25为延迟不可变性引入了稳定值API,并改进了应用程序启动_编程语言_A N M Bazlur Rahman_InfoQ精选文章