Add lazy-constants module: LazyConstant (JEP 531) against the holder idiom and double-checked locking

Basics, failure semantics on 26 vs 27, lazy collections, API across 25/26/27, preview-flag traps and a JMH read-path benchmark (jars fetched and sha1-checked, not committed).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
This commit is contained in:
Claude
2026-09-24 12:27:27 +00:00
parent af44e59e7f
commit 814c32b5ce
25 changed files with 606 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
// The three classic ways to hold a value that is expensive to build. Plain Java, no preview features.
public class OldWays {
static class Expensive {
final String how;
Expensive(String how) { this.how = how; System.out.println(" [init] building Expensive via " + how); }
}
// 1. Eager: built when OldWays is initialised, which is before main runs, whether or not anyone uses it.
static final Expensive EAGER = new Expensive("eager static final");
// 2. Holder idiom: the JVM initialises Holder the first time it is touched, and does so exactly once.
static class Holder { static final Expensive VALUE = new Expensive("holder idiom"); }
static Expensive holder() { return Holder.VALUE; }
// 3. Double-checked locking: correct only because the field is volatile.
private static volatile Expensive dcl;
static Expensive doubleChecked() {
Expensive local = dcl;
if (local == null) {
synchronized (OldWays.class) {
local = dcl;
if (local == null) dcl = local = new Expensive("double-checked locking");
}
}
return local;
}
public static void main(String[] args) {
System.out.println("main starts (the eager value already exists)");
System.out.println("first holder() call:"); holder();
System.out.println("second holder() call:"); holder();
System.out.println("first doubleChecked() call:"); doubleChecked();
System.out.println("second doubleChecked() call:"); doubleChecked();
}
}