Luk*_*kas 1 java getter lazy-loading lazy-evaluation lazy-initialization
以下内容与其说是一个问题,不如说是一个评估请求。
因此,您很可能熟悉以下惰性 getter 模式。
private Object obj;
public Object getObject() {
if(obj==null) {
obj = new Object();
}
return obj;
}
Run Code Online (Sandbox Code Playgroud)
那个代码
所以最近一个同事和我想出了以下界面(简化):
public interface LazyGetterSupport {
default Object get(Supplier<Object> impl) {
String key = impl.getClass().getName();
Object retVal;
if ((retVal = getInstanceCache().get(key)) == null) {
retVal = impl.get();
getInstanceCache().put(key, retVal);
}
return retVal;
}
Map<String, Object> getInstanceCache();
}
Run Code Online (Sandbox Code Playgroud)
旁注:不使用 HashMap#computeIfAbsent bc of Bug-8071667
然后该接口由您要使用惰性获取器的类实现。您需要提供getInstanceCache()如下实现:
private Map<String, Object> instanceCache;
@Override
public Map<String, Object> getInstanceCache() {
if (instanceCache == null) {
instanceCache = new HashMap<>();
}
return instanceCache;
}
Run Code Online (Sandbox Code Playgroud)
但鉴于您可以开始重写该类(和子类)中的所有其他惰性 getter,如下所示:
public Object getObject() {
return get(Objetct::new);
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为我们impl.getClass().getName();在接口中使用的键实际上对于我们在其 get 方法的实现中使用的每个 lambda 始终是唯一的。然而,至少在我们的 VM 的生命周期内,每个调用站点都将保持不变。
好处是显而易见的。我们不再需要为每个惰性吸气剂创建一个类变量,吸气剂本身变得更短。这可能没有什么不同,但在我们的用例中,我们经常有包含 20 多个 UI 元素的 Lazy Getter 的类。这就是这项新技术大放异彩的地方。
我很想知道您对这种方法的看法,以及您是否对在生产中使用它有任何顾虑。