为何使用BiPredicate时未触发短路逻辑,导致NullPointerException?
问题解析
首先明确两段代码的核心差异点:
第一个if语句中的
obj == null || obj.getSomeMethod() == null是Java原生的短路逻辑或:当左侧条件obj == null为true时,右侧的obj.getSomeMethod()会被直接跳过执行,因此不会触发NullPointerException。第二个调用
result(...)抛出异常,根本不是BiPredicate里的逻辑或不短路,而是Java方法调用的参数求值规则导致的:在调用result方法前,所有实参都会被预先计算。这里第三个实参是obj.getSomeMethod(),此时obj已经为null,所以在传递参数的阶段就直接抛出了NullPointerException,根本没机会进入BiPredicate.test()方法执行内部的逻辑或判断。
如果想让第二个场景也实现短路效果,可以通过Supplier延迟参数求值,修改后的示例代码如下:
public static void main(String[] args){ SomeObj obj = null; if (obj == null || obj.getSomeMethod() == null) { System.out.println("Obj is null"); } // 用Supplier延迟第二个参数的求值逻辑 if (result((x, ySupplier) -> x == null || ySupplier.get() == null, obj, () -> obj.getSomeMethod())) { System.out.println("Obj is null"); } } private static <X, Y> boolean result(final BiPredicate<X, Supplier<Y>> p, final X argX, final Supplier<Y> argYSupplier){ return p.test(argX, argYSupplier); }
这样只有当BiPredicate内的左侧条件x == null为false时,才会调用ySupplier.get()执行obj.getSomeMethod(),从而实现短路逻辑。
内容的提问来源于stack exchange,提问作者MLeiria
相关产品推荐
相关产品推荐

