Lazy field initialization with lambdas

后端 未结 14 2281
日久生厌
日久生厌 2020-11-29 23:39

I would like to implement lazy field initialization (or deferred initialization) without an if statement and taking advantage of lambdas. So, I would like to have the same b

14条回答
  •  萌比男神i
    2020-11-30 00:21

    Here's a solution using Java's Proxy (reflection) and Java 8 Supplier.

    * Because of the Proxy usage, the initiated object must implement the passed interface.

    * The difference from other solutions is the encapsulation of the initiation from the usage. You start working directly with DataSource as if it was initialized. It will be initialized on the first method's invocation.

    Usage:

    DataSource ds = LazyLoadDecorator.create(() -> initSomeDS(), DataSource.class)
    

    Behind the scenes:

    public class LazyLoadDecorator implements InvocationHandler {
    
        private final Object syncLock = new Object();
        protected volatile T inner;
        private Supplier supplier;
    
        private LazyLoadDecorator(Supplier supplier) {
            this.supplier = supplier;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (inner == null) {
                synchronized (syncLock) {
                    if (inner == null) {
                        inner = load();
                    }
                }
            }
            return method.invoke(inner, args);
        }
    
        protected T load() {
            return supplier.get();
        }
    
        @SuppressWarnings("unchecked")
        public static  T create(Supplier supplier, Class clazz) {
            return (T) Proxy.newProxyInstance(LazyLoadDecorator.class.getClassLoader(),
                    new Class[] {clazz},
                    new LazyLoadDecorator<>(supplier));
        }
    }
    

提交回复
热议问题