value() returns a Supplier , and the thing field is of type Lazy<Thing> . You cannot assign Supplier a Lazy (with any parameterization), because not all Supplier instances are Lazy instances.
In addition, lazily() returns the Supplier value) for the thing , and this will not work for the same reason.
We can change the lazily type to Lazy and remove the inline thing= assignment (which is inside the thing expression) to compile it:
static <U> Lazy<U> lazily(Lazy<U> lazy) { return lazy; } static <T> Supplier<T> value(T value) { return ()->value; } private static Lazy<Thing> thing = lazily(()->value(new Thing()));
But I'm not sure that this is what you wanted to get.
If you just wanted lazy behavior, the Supplier itself is already lazy, because get() is executed only on request, and not when creating the Supplier .
If you need caching logic (only calculate once and only need to calculate it), you can use something like this:
public class CachingSupplier<T> implements Supplier<T> { private final Supplier<T> supplier; private T cachedValue; private boolean computed = false; public CachingSupplier(Supplier<T> supplier) { this.supplier = supplier; } public T get() { if (!computed) { cachedValue = supplier.get(); computed = true; } return cachedValue; } }
If you want to guarantee that supplier.get() will be called at most once, you can apply some synchronization:
if (!computed) { synchronized (this) { if (!computed) { cachedValue = supplier.get(); computed = true; } } } return cachedValue;
A double-checked lock is used here.
source share