大家好,这里是架构资源栈!点击上方关注,添加“星标”,一起学习大厂前沿架构!
在 JDK 25 中,Java 正式引入了一个全新 API —— Stable Values。这个特性源自 JEP 502,最初被称为 “Computed Constants”,如今已标记为完成状态,成为 Java 平台对懒加载与不可变性支持的全新尝试。
Stable Values 的核心理念是:“可延迟初始化的不可变值”。开发者可以创建只赋值一次的对象,这些对象在首次赋值之后即成为不可变。这一特性融合了 final
字段的性能优势与懒加载的灵活性,为提升应用启动性能提供了新路径。
为什么需要 Stable Values?
在传统 Java 设计中,final
字段需要在构造函数或静态块中立即初始化。而懒加载则往往借助 null
判断 + 可变字段实现:
// 传统懒加载方式:线程不安全,影响性能优化
class OrderController {
private Logger logger = null;
Logger getLogger() {
if (logger == null) {
logger = Logger.create(OrderController.class);
}
return logger;
}
}
这种做法不仅影响 JVM 的优化能力(如常量折叠),还容易引入线程安全问题。而 Stable Values 正是为了解决这一矛盾而生。
StableValue 的核心用法
新 API 引入了 StableValue<T>
类,它允许在运行时对值执行一次性初始化。最常用的初始化方式是 orElseSet()
:
import java.lang.StableValue;
class OrderController {
private final StableValue<Logger> logger = StableValue.of();
Logger getLogger() {
return logger.orElseSet(() -> Logger.create(OrderController.class));
}
}
orElseSet()
支持线程安全、仅执行一次的初始化逻辑- 一旦被赋值,该值将永久保持不可变
- JVM 可以对其进行与
final
字段等效的优化处理
更多高级用法:懒加载连接、延迟初始化集合等
Stable Values 不只是单值容器,它还扩展出如下几种变体:
1. Stable Supplier:定义时指定初始化逻辑
class DataService {
private final Supplier<DatabaseConnection> connection =
StableValue.supplier(() -> new DatabaseConnection("jdbc:postgresql://localhost/db"));
void performQuery() {
DatabaseConnection db = connection.get(); // 首次调用时初始化
}
}
这种方式特别适用于依赖注入或连接池等场景,避免无谓的资源占用。
2. Stable List:集合级懒加载
class ThreadPool {
private final List<WorkerThread> workers =
StableValue.list(POOL_SIZE, index -> new WorkerThread(index));
WorkerThread getWorker(int index) {
return workers.get(index); // 首次访问对应元素时初始化
}
}
相比一次性初始化整个集合,Stable List 支持“按需创建”,提升了启动与内存性能。
JVM 如何优化 Stable Values?
Stable Values 的设计核心在于内部使用了 @Stable
注解(JDK 内部特性),这是一个对 JVM 的提示:虽然字段不是 final,但只会被写入一次。
这使得 JVM 能够像优化 final
字段一样,对 StableValue 的值进行内联、常量折叠等高级优化。这种设计兼顾了语义安全与执行效率。
启动性能的利器:延迟加载控制器与服务
以典型的大型应用为例,我们可以通过 Stable Values 实现“按需加载”各个模块,显著提升首次启动速度:
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);
}
}
当用户访问订单模块时,控制器才会被实例化。对于启动后不一定立即使用的功能,这种机制极大减少了资源初始化的浪费。
启用方式与注意事项
目前 Stable Values 仍处于“预览状态”,在使用时需要明确启用:
javac --release 25 --enable-preview MyApplication.java
java --enable-preview MyApplication
这一阶段旨在收集社区反馈,为最终定案做准备。
写在最后
Java 25 的 Stable Values API,标志着 Java 对启动优化与懒加载模式的再进化。它提供了一种线程安全、语义明确且性能优越的懒初始化手段,帮助开发者更灵活地管理复杂对象的创建时机。
未来,在更多实际项目中引入 Stable Values,有望为大型企业应用、微服务系统乃至框架开发提供全新的性能与设计思路。
推荐理由一句话总结:
用StableValue
,取代旧式懒加载,从此不再手写if (xxx == null)
!
转自:https://mp.weixin.qq.com/s/t9Cacp8aXrML5eSWFr18OA