Short Circuit Evaluation Reading
Here’s a table describing two of Java’s boolean operators:
Operator | Meaning |
---|---|
&& | and |
|| | or |
The &&
and ||
operators are short circuit logical operators. A short circuit operator is one that doesn’t necessarily evaluate all of its operands. Take, for example, the operator &&
. What happens when Java executes the following code?
if (0 == 1 && 2 + 2 == 4) {
System.out.println("This line won't be printed.");
}
You might expect Java to ask itself if 0
equals 1
, then ask if 2 + 2
equals 4
, and finally check if both are true. But with Java’s &&
operator, that’s not what happens. Instead, Java does the following:
- Evaluates
0 == 1
, discovering that0 == 1
isfalse
. - Realizes that the condition
(0 == 1 && whatever)
can’t possibly betrue
, no matter what thewhatever
condition happens to be, since both sides of an&&
must betrue
. - Returns
false
without bothering to check if2 + 2 == 4
.
To summarize, the condition (0 == 1 && whatever)
has to be false
, because 0 == 1
is false
. Remember, the &&
operator wants both conditions - on its left and right sides - to be true
.
When Java finds the value on the left side of an &&
operator to be false
, Java gives up and declares the entire expression to be false
. That’s called short circuit expression evaluation. The same kind of thing happens with the ||
operator when the value of the operator’s left side is true
. What happens when Java executes the following code?
if (2 + 2 == 4 || 0 == 1) {
System.out.println("This line will be printed.");
}
Here’s how Java’s ||
operator behaves when it encounters this code:
- Evaluates
2 + 2 == 4
, discovering that2 + 2 == 4
istrue
. - Realizes that the condition
(2 + 2 == 4 || whatever)
must betrue
, no matter what the whatever condition happens to be, since either side of the||
must betrue
. - Returns
true
without bothering to check if0 == 1
.
To summarize, the condition (2 + 2 == 4 || whatever)
has to be true
, because 2 + 2 == 4
is true
. Remember, the ||
operator wants either conditions - on its left or right side or on both sides - to be true
.
When Java finds the value on the left side of an ||
operator to be true
, Java declares the entire expression to be true
.
You may wonder, why do I care that these logical operators short circuit? Consider the following code:
public class NullChecks {
public void test() {
String testString = null;
if (testString != null && testString.equals("42")) {
System.out.println("This String is the meaning of life!");
} else {
System.out.println("This String was NOT the meaning of life!");
}
if (testString.equals("42") && testString != null) {
System.out.println("This String is the meaning of life!");
} else {
System.out.println("This String was NOT the meaning of life!");
}
}
}
What do you think the output of the test
method is? Go ahead and take a minute, I’ll wait.
…
So what did you think? If you run this code, you should see this output:
This String was NOT the meaning of life!
Exception in thread "main" java.lang.NullPointerException
at NullChecks.main(Test.java: 73)
Let’s take a look at why we get this output! In the first if check on line 6, Java first tests to see if testInteger != null
. This evaluates to false
. As we saw previously (testInteger != null && whatever)
has to be false
, so this code is short circuited. Therefore, Java drops into the else and prints out "This string was NOT the meaning of life!"
. In the second if check on line 12, Java first tests to see if testInteger.intValue() == 42
. Since testInteger
is null
, you are attempting to call the intValue()
method on a null
object. When a method is called on a null
object, a NullPointerException
is thrown as you can see here. Here you can see the power of short circuiting! It is often used to prevent NullPointerException
s.