39

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?

Raedwald
  • 46,613
  • 43
  • 151
  • 237
Shades88
  • 7,934
  • 22
  • 88
  • 130

6 Answers6

72

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
10

You can use StringUtils:

import org.apache.commons.lang3.StringUtils;

if (StringUtils.isBlank(str)) {

System.out.println("String is empty");

} else { 

System.out.println("String is not empty");

}

Have a look here also: StringUtils.isBlank() vs String.isEmpty()

isBlank examples:

StringUtils.isBlank(null)      = true
StringUtils.isBlank("")        = true  
StringUtils.isBlank(" ")       = true  
StringUtils.isBlank("bob")     = false  
StringUtils.isBlank("  bob  ") = false
Community
  • 1
  • 1
Rohit Taneja
  • 179
  • 1
  • 6
5

The problem here is that in your code the program is calling 'null.length()' which is not defined if the argument passed to the function is null. That's why the exception is thrown.

phew
  • 808
  • 1
  • 15
  • 34
  • 2
    It never gets to that part of the `if` if `str == null`. – Keppil Aug 26 '12 at 19:51
  • 2
    in the if (str == null || str.length() == 0) condition, the second part would never be evaluated if the first is false. If you do want the second part to be evaluated, you would write it as if (str == null | str.length() == 0) so you can get a nullpointer. Don't see why you would want it in this case but in some cases this could be beneficial. – Nikola Yovchev Aug 26 '12 at 19:56
  • 2
    actually it does. || is lazy, but he uses | which will evaluate both sides – Zoltan Balazs Aug 26 '12 at 19:58
  • @baba I got it. Excellent point. `||` works as a short circuit operator, so once evaluated to true it won't reach to next part. As `|` was being used, null.length was evaluated which produced exception – Shades88 Aug 26 '12 at 20:00
4

The problem is that you are using the bitwise or operator: |. If you use the logical or operator, ||, your code will work fine.

See also:
http://en.wikipedia.org/wiki/Short-circuit_evaluation
Difference between & and && in Java?

Community
  • 1
  • 1
Jeffrey
  • 44,417
  • 8
  • 90
  • 141
1

Change Below line

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

into

if (str == null || str.isEmpty()) {

now your code will run corectlly. Make sure str.isEmpty() comes after str == null because calling isEmpty() on null will cause NullPointerException. Because of Java uses Short-circuit evaluation when str == null is true it will not evaluate str.isEmpty()

Menuka Ishan
  • 5,164
  • 3
  • 50
  • 66
0

The | and & check both the sides everytime.

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

here we have high possibility to get NullPointerException

Logical || and && check the right hand side only if necessary.

but with logical operator

no chance to get NPE because it will not check RHS

NPE
  • 429
  • 2
  • 16