Or, better yet, using value factory Function instead of Supplier:


public class WeakFactoryClassValue<T> extends ClassValue<T> {
private final WeakReference<Function<? super Class<?>, ? extends T>> factoryRef;

public WeakFactoryClassValue(Function<? super Class<?>, ? extends T> factory) {
        factoryRef = new WeakReference<>(factory);
    }

    @Override
    protected T computeValue(Class<?> type) {
        Function<? super Class<?>, ? extends T> factory = factoryRef.get();
        if (factory == null) {
throw new IllegalStateException("Value factory function has already been GCed");
        }
        return factory.apply(type);
    }
}


The example would then read:

public class MyApp {
    // make VALUE_FACTORY stay at least until MyApp class is alive
private static final Function<Class<?>, Object> VALUE_FACTORY = clazz -> MyApp.CV;

    public static final ClassValue<Object> CV =
        new WeakFactoryClassValue<>(VALUE_FACTORY);

    public static void main(String[] args) {
        // this is OK
        CV.get(MyApp.class);

        // even this is OK, it makes CV reachable from Object.class,
        // but VALUE_FACTORY is only weakly reachable
        CV.get(Object.class);
    }
}



Regards, Peter



On 11/09/2016 01:31 PM, Peter Levart wrote:
The above situation could be prevented by a special concrete > ClassValue implementation, provided by the platform (loaded by >
bootstrap CL): > > public class WeakSupplierClassValue<T> extends ClassValue<T> { > private final WeakReference<Supplier<T>> supplierRef; > > public WeakSupplierClassValue(Supplier<T> supplier) { supplierRef = > new WeakReference<>(supplier); } > > @Override protected T computeValue(Class<?> type) { Supplier<T> > supplier = supplierRef.get(); if (supplier == null) { throw new > IllegalStateException("Supplier has already been GCed"); } return > supplier.get(); } } > > > ...with such utility class, one could rewrite above example to: > > public class MyApp { // make CV_SUPPLIER stay at least until MyApp > class is alive private static final Supplier<Object> CV_SUPPLIER = () > -> MyApp.CV; > > public static final ClassValue<Object> CV = new > WeakSupplierClassValue<>(CV_SUPPLIER); > > public static void main(String[] args) { // this is OK > CV.get(MyApp.class); > > // even this is OK, it makes CV reachable from Object.class, // but > CV_SUPPLIER is only weakly reachable CV.get(Object.class); } } > > > Regards, Peter

Reply via email to