空合并操作符的替代方法
使用Java,为了安全地访问像abcde
这样的深层嵌套的引用,我们通常必须在每个级别指定空的检查,或者在Optional
s中使用orElse()
。 (与像Kotlin / C#这样a?.b?.c?.d?.e
语言不同的是, a?.b?.c?.d?.e
或类似的语言。
我想知道下面的辅助方法是否是一个合理的选择:
public T valueOrNull(Supplier expression) { try { return expression.get(); } catch (NullPointerException e) { return null; } }
这可以安全地使用value = valueOrNull(() -> abcde)
。
注意:我明白捕获NullPointerException
通常是由于性能原因等原因而皱起眉头,但想知道这里的用法是否是一个合理的例外。
你可以编写一个函数来获得一个值和一个getter来转换它,像这样
public static T1 coalesce(T2 value, Function f1){ return f1.apply(value); }
然后你会这样调用coalesce(value, Clazz::getA)
。
对于链中的每一步,您都需要在合并函数中添加一个额外的函数,如下所示
public static T1 coalesce(T3 value, Function f1, Function f2){ T2 t2 = f1.apply(value); if(t2 == null) return null; return f2.apply(t2); }
为两个深度,和
public static T1 coalesce(T4 value, Function f1, Function f2, Function f3){ T3 t3 = f1.apply(value); if(t3 == null) return null; T2 t2 = f2.apply(t3); if(t2 == null) return null; return f3.apply(t2); }
深度为三等深度。
示例代码:
A test1 = new A(null); A test2 = new A(new B(null)); A test3 = new A(new B(new C(null))); A test4 = new A(new B(new C("1234"))); System.out.println(coalesce(test1, A::getB, B::getC, C::getS)); System.out.println(coalesce(test2, A::getB, B::getC, C::getS)); System.out.println(coalesce(test3, A::getB, B::getC, C::getS)); System.out.println(coalesce(test4, A::getB, B::getC, C::getS)); System.out.println(coalesce(test2, A::getB)); System.out.println(coalesce(test3, A::getB, B::getC));
A是具有B类成员的类,B是具有C类成员的类,C是具有类String成员的类,具有适当的获取者。 产出如预期:
null null null 1234 B@776ec8df C@41629346
前三种情况为空,C中的字符串为空,第四种为字符串的值,第五种和第六种types为B和C的返回对象分别为空。
我不知道如何让代码更短,不幸的是。