1

why when I use the below code eclipse highlights (!line.equals("")) with red and says: null pointer access: The variable line can only be null at this location

but I do not receive that warning message if I used : && instead of ||?

code:

String line = br.readLine();
        if ( (line != null) || (!line.equals("")) ) {
        } else {
            Log.d(TAG, "main", "file is empty");
        }
rmaik
  • 1,076
  • 3
  • 15
  • 48
  • because you can still enter the later condition which could throw a nullpointerexception.. In other words, when the first condition fails, the second will throw an exception – SomeJavaGuy Aug 05 '15 at 11:23
  • Do you by chance mean `(line == null)` instead of `(line != null)`? The condition otherwise looks weird (and yes, it will result in a null pointer exception when `line` is `null`). – d125q Aug 05 '15 at 11:24

6 Answers6

3

Because &&(Logical And) will check conditions in order and if any of the condition is false it will not check next condition. Where as ||(Logical Or) will check until one of the condition is true.

So if you use || there is a possibility that first condition (i.e. line != null) is false and it will go to next condition (i.e. !line.equals("")) and throw NullPointerException.

And @piet.t rightly pointed that if first condition is true then it will not do blank check also if you are using ||.


You might also be interested in Difference between & and && in Java?

Community
  • 1
  • 1
Naman Gala
  • 4,670
  • 1
  • 21
  • 55
3

Because you have an OR (||) operator, Java will determine the value of

line != null

and if this is false (if line is null)

!line.equals("")

Hence the second will be executed when line is null, and dereference a null pointer. Your IDE is correct to highlight this issue.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
3

This is a classic "short circuit".

For the && case:

if ((line != null) && (!line.equals("")) {

If line does equal null, then there is no reason for the compiler to process the second part of the if statement. The whole if statement MUST be false. So it short circuits the second part of the if statement, and you don't get the null reference exception.

When you switch the && to ||, then the compiler does have to process the second part of the if statement, because if either part is true then the whole thing is true. Therefore, you can get the null reference exception.

Note: If you can also use StringUtils of the Apache commons-lang to both checks in one:

if (StringUtils.isNotBlank(str))

Update: For the || case, if the first part were true, then the whole if statement must be true, so again there is no reason to process the second part of the if statement.

Mike
  • 335
  • 4
  • 20
1

It is because of the operator || Java has to evaluate both of conditions the give the result. When Java will try the second condition he will fail with the npe.

bryce
  • 842
  • 11
  • 35
1

Because in the case of && !line.equals("") is only checked if line != null is true unlike || when line != null is true compiler dint check !line.equals("") statement and exits if()

singhakash
  • 7,891
  • 6
  • 31
  • 65
1

&& is a "short-circuit" operator. It means, if the left condition (line != null) fails, right condition will not be evaluated, so there is no risk of a NullPointerException. To determine the outcome of OR, both conditions must be evaluated (regardless of the short-circuit operator). Hence the warning.

Amila
  • 5,195
  • 1
  • 27
  • 46
  • `||` is also a "short-circuit"-operator and may skip the second check if the first evaluates to `true`! – piet.t Aug 05 '15 at 11:42