空合并操作符的替代方法

使用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的返回对象分别为空。

我不知道如何让代码更短,不幸的是。