...
The bitwise AND and OR operators (&
and |
) do not exhibit this behavior. They, like Like most other Java operators, they evaluate both operands, starting with first the left operand, and then the right. They return the same Boolean result as &&
and ||
respectively, but can have different overall effect depending on the presence or absence of side-effects in the second operand.
Consequently it is useful to use either the &
or the &&
operator can be used when performing Boolean logic. However, there are times when the short-circuiting behavior is preferred, and other times when the short-circuiting behavior causes subtle bugs.
Noncompliant Code Example (Improper &
)
Wiki Markup |
---|
In thisThis noncompliant code example, derived from \[[Flanagan 2005|AA. Bibliography#Flanagan 05]\], we havehas two variables, with no guarantees as toregarding their current values. The code attempts to must validate its data and then check ifwhether {{array[i]}} is nonnegative, but first it must validate its data. |
Code Block | ||
---|---|---|
| ||
int array[]; // may be null int i; // may be a valid index for array if (array != null & i >= 0 & i < array.length & array[i] >= 0) { // handle array } else { // handle error } |
Unfortunately this This code may can fail due to the very errors it is trying attempting to prevent. If When array
is null or when i
is not a valid index, the reference to arrayi
will cause a NullPointerException
or an ArrayIndexOutOfBoundsException
to be thrown. This happens because the &
operator does not fails to prevent evaluation of its right operands from being evaluatedoperand, even if when evaluation of its left operands prove that they are operand proves that the right operand is invalid.
Compliant Solution (Use &&
)
...
This compliant solution uses multiple if statements to achieve the proper effect. While correct, it is more verbose and may be more difficult to maintain.
Code Block | ||
---|---|---|
| ||
int array[]; // may be null int i; // may be a valid index for array if (data != null) { if (i >= 0 & i < data.length) { if (data[i] != -1) { // handle array } else { // handle error } } else { // handle error } } else { // handle error } |
This Nevertheless, this solution could would be useful if the error-handling routines for each potential condition failure were different.
...
The problem with this code is that if when the first condition in the while loop fails, the second condition is not executed. That is, once i1
has reached array1.length
, the loop may terminate after i1
is executed. Consequently the range over array1
is larger than the range over array2
, causing the final assertion to fail.
...