Thursday, May 28, 2026

Java 26: Lazy Constants

In my previous post, I wrote about Stable Values introduced in Java 25. Java 26 renames them from Stable Values to Lazy Constants. While the underlying idea remains the same, the new name better reflects the intended use case: immutable values that are initialised lazily. This is a preview language feature.

A Lazy Constant allows you to defer the initialisation of immutable data until it is actually needed, while still allowing the JVM to optimise access to that data as though it were a regular final field.

Here is the example from the previous post, rewritten using a LazyConstant:

public class Controller {

    private final LazyConstant<ExpensiveResource> resource =
            LazyConstant.of(() -> new ExpensiveResource());

    public void process(String request) {
        resource.get().get(request);
    }
}

Initially, the lazy constant is uninitialised. The first call to resource.get() invokes the lambda expression, creates the ExpensiveResource, stores it permanently, and returns it. Subsequent calls simply return the already initialised value. Importantly, the initialisation function is guaranteed to execute only once, even under concurrent access.

Under the hood, the content of a LazyConstant is stored in a non-final field annotated with the JDK-internal @Stable annotation. This tells the JVM that the field will never change after it is written. Due to this guarantee, the JVM can treat the value like a constant, provided that the reference to the stable value is final, and perform constant-folding optimisations, even through multiple layers of stable values.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.