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
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));
}
}