Home > front end >  Why BiPredicate evaluates the two boolean conditions prior to applying the test function
Why BiPredicate evaluates the two boolean conditions prior to applying the test function

Time:09-23

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
  • X
  • Y

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.

  • Related