Advertisement
Advertisement


&& (AND) and || (OR) in IF statements


Question

I have the following code:

if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){  
    partialHits.get(z).put(z, tmpmap.get(z));  
}

where partialHits is a HashMap.
What will happen if the first statement is true? Will Java still check the second statement? Because in order the first statement to be true, the HashMap should not contain the given key, so if the second statement is checked, I will get NullPointerException.
So in simple words, if we have the following code

if(a && b)  
if(a || b)

would Java check b if a is false in the first case and if a is true in the second case?

2018/03/30
1
138
3/30/2018 3:11:19 PM

Accepted Answer

No, it will not be evaluated. And this is very useful. For example, if you need to test whether a String is not null or empty, you can write:

if (str != null && !str.isEmpty()) {
  doSomethingWith(str.charAt(0));
}

or, the other way around

if (str == null || str.isEmpty()) {
  complainAboutUnusableString();
} else {
  doSomethingWith(str.charAt(0));
}

If we didn't have 'short-circuits' in Java, we'd receive a lot of NullPointerExceptions in the above lines of code.

2018/03/15
203
3/15/2018 12:39:20 AM

Java has 5 different boolean compare operators: &, &&, |, ||, ^

& and && are "and" operators, | and || "or" operators, ^ is "xor"

The single ones will check every parameter, regardless of the values, before checking the values of the parameters. The double ones will first check the left parameter and its value and if true (||) or false (&&) leave the second one untouched. Sound compilcated? An easy example should make it clear:

Given for all examples:

 String aString = null;

AND:

 if (aString != null & aString.equals("lala"))

Both parameters are checked before the evaluation is done and a NullPointerException will be thrown for the second parameter.

 if (aString != null && aString.equals("lala"))

The first parameter is checked and it returns false, so the second paramter won't be checked, because the result is false anyway.

The same for OR:

 if (aString == null | !aString.equals("lala"))

Will raise NullPointerException, too.

 if (aString == null || !aString.equals("lala"))

The first parameter is checked and it returns true, so the second paramter won't be checked, because the result is true anyway.

XOR can't be optimized, because it depends on both parameters.

2013/05/15

No it will not be checked. This behaviour is called short-circuit evaluation and is a feature in many languages including Java.


All the answers here are great but, just to illustrate where this comes from, for questions like this it's good to go to the source: the Java Language Specification.

Section 15:23, Conditional-And operator (&&), says:

The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true. [...] At run time, the left-hand operand expression is evaluated first [...] if the resulting value is false, the value of the conditional-and expression is false and the right-hand operand expression is not evaluated. If the value of the left-hand operand is true, then the right-hand expression is evaluated [...] the resulting value becomes the value of the conditional-and expression. Thus, && computes the same result as & on boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

And similarly, Section 15:24, Conditional-Or operator (||), says:

The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false. [...] At run time, the left-hand operand expression is evaluated first; [...] if the resulting value is true, the value of the conditional-or expression is true and the right-hand operand expression is not evaluated. If the value of the left-hand operand is false, then the right-hand expression is evaluated; [...] the resulting value becomes the value of the conditional-or expression. Thus, || computes the same result as | on boolean or Boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

A little repetitive, maybe, but the best confirmation of exactly how they work. Similarly the conditional operator (?:) only evaluates the appropriate 'half' (left half if the value is true, right half if it's false), allowing the use of expressions like:

int x = (y == null) ? 0 : y.getFoo();

without a NullPointerException.

2009/11/25

No, if a is true (in a or test), b will not be tested, as the result of the test will always be true, whatever is the value of the b expression.

Make a simple test:

if (true || ((String) null).equals("foobar")) {
    ...
}

will not throw a NullPointerException!

2009/11/25

Short circuit here means that the second condition won't be evaluated.

If ( A && B ) will result in short circuit if A is False.

If ( A && B ) will not result in short Circuit if A is True.

If ( A || B ) will result in short circuit if A is True.

If ( A || B ) will not result in short circuit if A is False.

2014/06/13

Source: https://stackoverflow.com/questions/1795808
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]