if statement checks for null but still throws a NullPointerException

Shades88 picture Shades88 · Aug 26, 2012 · Viewed 164.4k times · Source

In this code.

public class Test {
     public static void testFun(String str) {
         if (str == null | str.length() == 0) {
             System.out.println("String is empty");
         } else { 
             System.out.println("String is not empty");
         }
     }
     public static void main(String [] args) {
         testFun(null);
    }
}

We pass a null value to the function testFun. Compiles fine, but gives a NullPointerException in runtime, which I did not expect. Why is it throwing an exception, rather than evaluating the if condition to true and printing "String is empty"?


Suppose the value of the actual argument being passed to testFun is generated from some process. Assume that mistakenly a null value is returned by that process and is fed to testFun. If such is the case, how does one validate that the value passed to the function is null or not?

One (weird) solution may be by assigning the formal parameter to some variable inside the function and then testing it. But if there are many variables passed to the function, that might become tedious and unfeasible. So, how does one check for null values in such a scenario?

Answer

Jon Skeet picture Jon Skeet · Aug 26, 2012

The edit shows exactly the difference between code that works and code that doesn't.

This check always evaluates both of the conditions, throwing an exception if str is null:

 if (str == null | str.length() == 0) {

Whereas this (using || instead of |) is short-circuiting - if the first condition evaluates to true, the second is not evaluated.

See section 15.24 of the JLS for a description of ||, and section 15.22.2 for binary |. The intro to section 15.24 is the important bit though:

The conditional-or operator || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false.