bye stable values, enter lazy constants
    Sergey Bylokhov 
    bylokhov at amazon.com
       
    Thu Oct  2 03:05:54 UTC 2025
    
    
  
On 9/30/25 02:27, Maurizio Cimadamore wrote:
> In the new API, LazyConstant.of() is no longer present (unlike
> StableValue::of), so I don't think this is an issue (e.g. you _have_ to
> pass a lambda).
+1
> ```
> class Foo {
>      private static final LazyConstant<Logger> LOGGER =
> LazyConstant.of(() -> makeLogger(Foo.class));
> 
>      static Logger getLogger() {
>          return LOGGER.get();
>      }
> }
> ```
> 
> The "problem" here is that you have a LOGGER field, and the
> implementation of Foo can access that field directly, w/o calling
> `getLogger`. Fine. But what can you do with LOGGER if not calling its
> get() method (which is also what the getter does) ? I'd like to
> understand the concern better here.
Even if the LazyConstant field is marked as private, it is still accessible from within the scope of 
the class. That means it can be read and therefore initialized by other methods in the same class, 
or even externally via JNI/reflection/etc. This can trigger the evaluation of the lambda expression 
passed to the lazy factory, causing the value to be computed and stored, even if the intended public 
factory method was never called.
This is a problem if initialization order matters. For example, say Foo.getInstance() is supposed to 
initialize(and skip) LOGGER/LOGGER1/LOGGER2/etc in a specific order. If the class has multiple 
loggers (for terminal, filesystem, network, etc.), how can we prevent accidental access to the wrong 
logger? How do we make sure direct access does not allow premature or out-of-order initialization?
I am not saying this feature is absolutely necessary, but it is something we do get to some extent 
with the holder pattern.
>>  - Handling exceptions more robustly than the Holder idiom
> 
> If an exception is thrown while computing the value is never set on the
> lazy constant -- meaning the next call to `get` will re-generate the
> same exception. With holder idiom one of the issue is that exceptions
> are thrown during initialization of the holder class, which can
> sometimes add confusion.
It is the main improvement over the holder, and I really like it!
This is one of the reason the holder cannot be used in many places in the JDK.
-- 
Best regards, Sergey.
    
    
More information about the leyden-dev
mailing list