Chr*_*örz 7 java java-8 null-check
我正在使用旧版应用程序,在该应用程序中,我经常不得不访问像下面这样嵌套的属性:
a.getB().getC().getD().getE().getF()
Run Code Online (Sandbox Code Playgroud)
问题在于,在任何深度下,该值都可能为空。当然,我可以像这样检查每个深度:
public Optional<F> retrieveValue(A a) {
if(a != null && a.getB() != null && a.getB().getC() != null &&
a.getB().getC().getD() != null &&
a.getB().getC().getD().getE() != null &&
a.getB().getC().getD().getE().getF() != null) {
return Optional.of(a.getB().getC().getD().getE().getF());
} else {
return Optional.empty();
}
}
F existingOrCreated = retrieveValue(a).orElse(new F());
Run Code Online (Sandbox Code Playgroud)
但是我必须在许多地方对许多不同的对象执行此操作,因此这些检查会使代码膨胀。大多数情况下,对象不是非null,但是在少数情况下,对象为null。有没有一种更简洁的方法?我正在使用Java 8,但是无法更新提供的旧代码。
在回答我的问题之前,我想指出这些链应该首先避免。(检查Demeter定律)。
现在解决问题。因为与Kotlin等其他语言不同,Java 无法提供更简单的空值检查,因此在Java 8之前,您只能选择检查对象的每个级别。
但是由于Java 8提供了作为参数传递的函数,因此我开始使用此功能在Java中构建自己的“安全调用”:
public static <T> Optional<T> retrieveValue(Supplier<T> getter) {
try {
return Optional.ofNullable(getter.get());
} catch (NullPointerException e) {
return Optional.empty();
}
}
Run Code Online (Sandbox Code Playgroud)
我们首先来看一下在给定情况下如何调用此方法:
F f = retrieveValue(() -> a.getB().getC().getD().getE().getF()).orElse(new F());
Run Code Online (Sandbox Code Playgroud)
如您所见,我们只是将Supplierto 传递给retrieveValue一个try-catch块,NullPointerException并Optional.empty()在可能的情况下调用它,并在这种情况下返回一个。
这种try-catch方法的一个小缺点是,如果NullPointerException在检查过程中发生a,则它比代码中的简单null检查要慢。
这种方法的另一个优点是,该方法可用于任何深度的任何其他空检查,并且不依赖于特定的对象结构。
Node node = retrieveValue(() -> root.getNode().getNode()).orElse(new Node());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
160 次 |
| 最近记录: |