sla*_*hms 2 java optional java-8
假设我有下一段代码:
void doSmtng(A a){
if (a!=null){
B b = a.getB();
if (b != null){
C c = b.getC();
if (c != null){
d = c.getD();
}
}
}
doSmtngWithD(d);
}
Run Code Online (Sandbox Code Playgroud)
让我们说,我可以改变的,而不是获得API A,B,C,D我可以得到Optional<A>,Optional<B>等等.
编写更美观的代码以阻止所有这些空检查的正确方法是什么?另外,一旦变量(a,b,c,d ..)中的一个为空,有没有办法按照我的要求添加抛出异常?
另一种Optional方式,Holger在评论中也提到了这一点:
D d = Optional.ofNullable(a)
.map(A::getB)
.map(B::getC)
.map(C::getD)
.orElseThrow(/* your exception */);
Run Code Online (Sandbox Code Playgroud)
这可以按原样应用于您的代码.您无需重写访问器方法.null返回第一个值后抛出异常.但是当抛出异常时你不知道究竟是哪一个null.
如果你真的想知道这一点,你可能更好地实现一个简单的方法,它只是你的null-checks而不是使用Optional,例如
static <T> T mapIfNotNull(T value) {
if (value == null) {
// throw your exception...
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
并在没有您的条件的情况下使用它如下:
A a = ...
B b = mapIfNotNull(a.getB());
C c = mapIfNotNull(b.getC());
D d = mapIfNotNull(c.getD());
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以在每个步骤中抛出所需的异常...(例如,如果您提供了另外的参数,您可以在其中提供自定义异常mapIfNotNull(T value, Supplier<RuntimeException> exceptionSupplier)).或者只是Objects.requireNonNull在评论中使用Holger状态,如果NullPointerException满足您的需要.
如果您还想检查,您调用getXXon 的对象是否为null,则可能需要使用如下方法:
static <S, T> T map(S source, Function<S, T> mapFunction) {
if (source == null) { // or again: Objects.requireNonNull(source,..)
// throw exception due to source
}
T value = mapFunction.apply(source);
if (value == null) { // or Objects.requireNonNull(value,..)
// throw exception due to missing value
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
呼叫工作几乎相同:
A a = ...
B b = map(a, A::getB);
C c = map(b, B::getC);
D d = map(c, C::getD);
Run Code Online (Sandbox Code Playgroud)
从以下开始Optional<A> a:
a.flatMap(A::getOptionalB)
.flatMap(B::getOptionalC)
.flatMap(C::getOptionalD)
.ifPresent(d -> doSomethingWithD(d));
Run Code Online (Sandbox Code Playgroud)
如果您想丢失其中一个异常,则抛出异常:
D d = a.flatMap(A::getOptionalB)
.flatMap(B::getOptionalC)
.flatMap(C::getOptionalD)
.orElseThrow(() -> new SomeKindOfException());
doSomethingWithD(d);
Run Code Online (Sandbox Code Playgroud)