[フレーム]
BT

InfoQ Software Architects' Newsletter

A monthly overview of things you need to know as an architect or aspiring architect.

View an example

We protect your privacy.

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Unlock the full InfoQ experience

Unlock the full InfoQ experience by logging in! Stay updated with your favorite authors and topics, engage with content, and download exclusive resources.

Log In
or

Don't have an InfoQ account?

Register
  • Stay updated on topics and peers that matter to youReceive instant alerts on the latest insights and trends.
  • Quickly access free resources for continuous learningMinibooks, videos with transcripts, and training materials.
  • Save articles and read at anytimeBookmark articles to read whenever youre ready.

Topics

Choose your language

InfoQ Homepage News Java 25 Introduces Stable Values API for Deferred Immutability and Improved Application Startup

Java 25 Introduces Stable Values API for Deferred Immutability and Improved Application Startup

Jun 02, 2025 2 min read

Write for InfoQ

Feed your curiosity. Help 550k+ global
senior developers
each month stay ahead.
Get in touch
Listen to this article - 0:00
Audio ready to play
0:00
0:00

JEP 502, Stable Values (Preview), has been moved to Completed status for JDK 25. Formerly known as Computed Constants (Preview), this JEP introduces the concept of computed constants, defined as immutable value holders that are initialized at most once. The new API allows developers to create objects with "deferred immutability." These objects can be initialized once at any point during execution and remain immutable thereafter, combining the performance benefits of final fields with the flexibility of lazy initialization.

The Stable Values API specifically targets application startup performance issues caused by eager initialization of complex objects. Unlike final fields, which must be initialized during construction or class initialization, stable values can be initialized on-demand while also enabling JVM constant-folding optimizations typically reserved for final fields. This is still a Preview feature.

The Stable Values API centers around the StableValue class, which holds a single data value that can be set exactly once. The primary initialization method, orElseSet(), ensures thread-safe, at-most-once initialization even under concurrent access:

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

This approach eliminates common pitfalls associated with traditional lazy initialization patterns. Without stable values, developers typically resort to mutable fields with null-checking, which prevents JVM optimizations and introduces thread safety concerns:

// Traditional approach - loses optimization opportunities
class OrderController {
 private Logger logger = null; // Mutable field
 
 Logger getLogger() {
 if (logger == null) {
 logger = Logger.create(OrderController.class);
 }
 return logger;
 }
}

The API extends beyond basic stable values to include stable suppliers and stable lists. Stable suppliers allow initialization logic to be specified at declaration time while deferring actual execution:

class DataService {
 private final Supplier<DatabaseConnection> connection = 
 StableValue.supplier(() -> new DatabaseConnection("jdbc:postgresql://localhost/db"));
 
 void performQuery() {
 DatabaseConnection db = connection.get();
 // Database connection created only on first access
 }
}

Stable lists support collections where individual elements are initialized independently as accessed:

class ThreadPool {
 private final List<WorkerThread> workers = 
 StableValue.list(POOL_SIZE, index -> new WorkerThread(index));
 
 WorkerThread getWorker(int index) {
 return workers.get(index); // Worker created only when first accessed
 }
}

The key advantage of stable values lies in their treatment by the JVM. Under the hood, stable values use the JDK-internal @Stable annotation, which signals to the JVM that, despite being stored in a non-final field, the value will not change after its initial update. This enables the same constant-folding optimizations available to final fields.

Stable values enable a fundamental rethinking of application initialization strategies. Applications can now defer the creation of expensive components until they are actually needed, dramatically improving startup times:

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);
 }
}

This pattern allows applications to start instantly, with components initialized on demand as the application's execution path requires them. The approach is particularly beneficial for large enterprise applications with numerous components, many of which may not be used during typical execution.

As a preview API, Stable Values require explicit enablement during compilation and runtime:

javac --release 25 --enable-preview MyApplication.java
java --enable-preview MyApplication

The preview status allows the development team to gather feedback from the Java community before finalizing the API design and implementation.

The Stable Values API in Java 25 offers a compelling solution to long-standing initialization challenges, providing developers with a tool that combines the safety and performance of immutable fields with the flexibility of lazy initialization.

About the Author

A N M Bazlur Rahman

Show moreShow less

Rate this Article

Adoption
Style

This content is in the Java topic

Related Topics:

Related Content

The InfoQ Newsletter

A round-up of last week’s content on InfoQ sent out every Tuesday. Join a community of over 250,000 senior developers. View an example

We protect your privacy.

BT

AltStyle によって変換されたページ (->オリジナル) /