pep*_*uch 8 java design-patterns
例如,在代码中,我们有很多链式方法obj.getA().getB().getC().getD().我想创建一个帮助类,它将检查方法getD()是否为null,但在此之前我需要检查所有以前的getter.我可以这样做:
try {
obj.getA().getB().getC().getD();
}
catch (NullPointerException e) {
// some getter is null
}
Run Code Online (Sandbox Code Playgroud)
或者(这是"愚蠢的")
if (obj!null && obj.getA()!=null && obj.getA().getB()!=null && ...) {
obj.getA().getB().getC().getD();
}
else {
// some getter is null
}
Run Code Online (Sandbox Code Playgroud)
我不想每次都try{} catch()在我的代码中使用它来检查它.为此目的,最佳解决方案是什么?
我认为最好的将是:
obj.getA().getB().getC().getD().isNull()- 为此我需要更改所有的getter,例如实现一些包含isNull()方法的接口.NullObjectHelper.isNull(obj.getA().getB().getC().getD()); - 这将是最好的(我想是这样),但如何实现这一点?从Java 8开始,您可以使用Optional.isPresent和Optional.orElse等方法来处理getter链中的null:
boolean dNotNull = Optional.ofNullable(obj)
.map(Obj::getA)
.map(A::getB)
.map(B::getC)
.map(C::getD)
.isPresent();
Run Code Online (Sandbox Code Playgroud)
虽然这比捕获NullPointerException更可取,但这种方法的缺点是Optional实例的对象分配.
可以编写自己的静态方法来执行类似的操作,而不会产生这种开销:
boolean dNotNull = Nulls.isNotNull(obj, Obj::getA, A::getB, B::getC, C::getD);
Run Code Online (Sandbox Code Playgroud)
没有方法可能比嵌套的if-not-null检查具有更高的运行时效率.
您可以使用Option模式获得所需的结果.这会强制您更改方法签名,但基本上如果您的方法返回某种类型T,它会保证它具有一些非null值,如果它返回Option<T>它意味着它具有值T或null.
Java 7有一些称为null安全的功能,但它已从最终版本中删除.你可以这样做:
obj?.getA()?.getB()?.getC()?.getD()
Run Code Online (Sandbox Code Playgroud)
此外,Java 8将添加一个名为的功能,Optional以便您安全地执行此操作.
事实上,如果你现在真的想使用它,试试Null Object模式.这意味着null您可以返回某种默认值而不是返回plain ,而不会触发NullPointerException.但是,您需要为getter添加一些更改
class Object {
A getA() {
// ...
return a == null ? A.NULL : a;
}
}
class A {
static A NULL = new A(); // some default behaviour
B getB() {
if (this == NULL) return B.NULL;
// ...
return b == null ? B.NULL : b;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:如果你想要实用程序,你可以将它包装在一些功能界面,然后调用它.
static boolean isNullResult(Callable call) throws Exception {
try {
return call.call() == null;
} catch (NullPointerException npe) {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
用法如下:
isNullResult(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return new A().getB().getC().getInt();
}
});
Run Code Online (Sandbox Code Playgroud)
它不需要您更改现有功能
| 归档时间: |
|
| 查看次数: |
3754 次 |
| 最近记录: |