Consider this sample code:
public static void main(String[] args){
SomeObj obj = null;
if (obj == null || obj.getSomeMethod() == null) {
System.out.println("Obj is null");
}
if (result((x, y) -> x == null || y == null, obj, obj.getSomeMethod())) {
System.out.println("Obj is null");
}
}
private static <X, Y> boolean result(final BiPredicate<X, Y> p, final X argX, final Y argY){
return p.test(argX, argY);
}
In the first If condition I get the message "obj is null" but in the second If condition I get a NullPointerException. This BiPredicate should't be a short circuit operator (if the first condition is true don't bother evaluating the second one)?
CodePudding user response:
No, you're passing three arguments to result:
- The
BiPredicate XY
They get evaluated before calling result, which means the BiPredicate is evaluated and returns a BiPredicate (which is not executed), then X is evaluated, than Y but Y is obj.getSomeMethod() and obj is null, so the NullPointerException is thrown.
CodePudding user response:
This actually has nothing to do with BiPredicate per se.
if (result((x, y) -> x == null || y == null, obj, obj.getSomeMethod())) {
is just invoking a method, in exactly the same way that
if (someMethod("Hello", obj, obj.getSomeMethod())) {
does: Java evaluates all of the arguments, and then passes them to the method.
So, it evaluates obj.someMethod(), whether or not obj is null. If it is null, you will get a NullPointerException here.
BiPredicate has no special support in the language: it's just a regular library-defined interface. You don't get any special lazy evaluation by using it.
