智能体刷屏的背后,是 AI 应用拐点的来临?AICon 北京站议程重磅公布,50+ 硬核分享不容错过 了解详情
写点什么

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:043

评论

发布
暂无评论

Sibelius西贝柳斯2023 mac永久使用 兼容M1/M2

Rose

Avid Sibelius 2023 Mac 西贝柳斯 Avid Sibelius

一键Run带你体验扩散模型的魅力

华为云开发者联盟

人工智能 华为云 华为云ModelArts 华为云开发者联盟

深入浅出:JavaScript 中 every() 的运作原理

Apifox

JavaScript 程序员 前端 数组 前端开发

office 2016专业增强版 含office2016激活工具 mac/win

Rose

office办公软件 Office 2016 下载 office2016破解版 Msoffce2016

【论文速读】| 大语言模型引导的协议模糊测试

云起无垠

MATLAB R2023b提示已停止工作怎么办?

Rose

数学软件 MATLAB R2023b

Shell 检查程序进程是否存在,自动重启

最爱小胖子

LLM 大模型框架 LangChain 可观测性最佳实践

心有千千结

观测云 LLM langchain

如何将应用一键部署至多个环境?丨Walrus教程

SEAL安全

MySQL 运维 应用部署 Walrus

Axure RP 10中文授权码及安装教程, 从交互设计到响应式原型

Rose

原型设计 软件下载 Axure RP 授权码 Axure RP 汉化包

国家科技传播中心讲坛!播出预告:吴甜——当机器学会思考

飞桨PaddlePaddle

人工智能 深度学习 百度 BAIDU 百度飞桨

[自研开源] MyData 数据集成任务的流程介绍 v0.7.1

LIEN

开源 数据集成 业务融合 API对接 mydata

文心一言 VS 讯飞星火 VS chatgpt (210)-- 算法导论16.1 1题

福大大架构师每日一题

福大大架构师每日一题

AI数字虚拟人来了你会失业吗?

小魏写代码

益和热力选择 TDengine,实现智慧供热系统升级

TDengine

tdengine 时序数据库

一文读懂私网解析 PrivateZone

火山引擎边缘云

DNS DNS服务器 DNS劫持 #DNS

软件测试团队管理技巧 | 提升团队效能:如何与下属进行有效沟通

测试人

软件测试

探索AI的边界:如何精准地测试人工智能

测吧(北京)科技有限公司

测试

管理技巧 | 提升团队效能:如何与下属进行有效沟通

测吧(北京)科技有限公司

测试

英伟达要小心了!爆火的Groq芯片能翻盘吗?AI推理速度「吊打」英伟达?

GPU算力

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