<i18n dev> RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v20]

Chen Liang liach at openjdk.org
Wed Nov 5 23:34:14 UTC 2025


On Fri, 24 Oct 2025 09:01:10 GMT, Per Minborg <pminborg at openjdk.org> wrote:

>> Implement JEP 526: Lazy Constants (Second Preview)
>> 
>> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class.
>> 
>> The old benchmarks are not moved/renamed to allow comparison with previous releases.
>> 
>> `java.util.Optional` is updated so that its field is annotated with `@Stable`.  This is to allow `Optional` instances to be held in lazy constants and still provide constant folding.
>
> Per Minborg has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Rework toString implementations

src/java.base/share/classes/java/lang/LazyConstant.java line 94:

> 92:  * lazy constant remains uninitialized.
> 93:  *
> 94:  * <h2 id="composition">Composing lazy constants</h2>

This section has some interesting usage, but I don't believe it should be included in the API specification. Behaviors described here can be derived from the formal specifications.

src/java.base/share/classes/java/lang/LazyConstant.java line 209:

> 207: 
> 208:     /**
> 209:      * {@return the contents of this lazy constant if initialized, otherwise,\

Suggestion:

     * {@return the contents of this lazy constant if initialized, otherwise,

src/java.base/share/classes/java/util/AbstractMap.java line 34:

> 32: 
> 33: import jdk.internal.vm.annotation.AOTSafeClassInitializer;
> 34: import jdk.internal.vm.annotation.Stable;

Suggestion:

src/java.base/share/classes/java/util/Currency.java line 146:

> 144:     private static ConcurrentMap<String, Currency> instances = new ConcurrentHashMap<>(7);
> 145:     private static final LazyConstant<HashSet<Currency>> available =
> 146:             LazyConstant.of(new Supplier<HashSet<Currency>>() {

Why can't we retain the method reference here? This is not used in early bootstrap.

src/java.base/share/classes/java/util/LazyCollections.java line 516:

> 514: 
> 515:         @ForceInline
> 516:         private void disposeOfMutex(long offset) {

I recommend removing this unused and otherwise confusing method.

src/java.base/share/classes/java/util/LazyCollections.java line 559:

> 557:     }
> 558: 
> 559:     public static <E> int lastIndexOf(List<LazyConstant<E>> list, Object o) {

This indexOf and lastIndexOf appear unused.

src/java.base/share/classes/java/util/Map.java line 1814:

> 1812:         final Set<K> keyCopies = Set.copyOf(keys);
> 1813:         Objects.requireNonNull(computingFunction);
> 1814:         if (keys instanceof EnumSet<?> && !keys.isEmpty()) {

I wonder if it's premature for us to optimize like this - for example, this would be wasteful if the key set contains one enum constant but there are 1000 enum constants in this enum.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2496459406
PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2496468213
PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2496478562
PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2496479687
PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2496503928
PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2496514844
PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2496516750


More information about the i18n-dev mailing list