When used with boolean
operands, &
and |
become logical operators per Section 15.22.2 of the JLS. Unlike &&
and ||
, however, these don't short-circuit; they always evaluate both sides. I have a silly question: Why are the less-efficient non-short-circuit logical operators (&
, |
) still there, when we have the more-efficient short-circuit logical operators (&&
, ||
)? I mean, what is the real usage of the non-short-circuit logical operators, as opposed to with the short-circuit logical operators? In other words, what is the usage of always evaluating both sides by using the non-short-circuit logical operators?
Updated answer:
Apologies, I missed the word "logical" in your question even though it is there. (I've taken the liberty of emphasizing it a bit with an edit.)
Consider the case where you want any side-effects to always occur, regardless of whether the left-hand expression evaluates true
or false
. E.g., contrast:
if (foo() & bar()) {
// Only call this if both operations returned true
}
with
if (foo() && bar()) {
// Only call this if both operations returned true
}
Let's assume both foo
and bar
have effects that we want to have happen regardless of whether foo
returns true
or false
. In the first one above, I know that bar
will always get called and have its effect. In the latter, of course, bar
may or may not get called. If we didn't have the non-short-circuit version, we'd have to use temporary variables:
boolean fooResult, barResult;
fooResult = foo();
barResult = bar();
if (fooResult && barResult) {
// ...
}
You might argue (I probably would) that you should do that anyway, because it's way too easy to misread if (foo() & bar())
, but there we go, a pragmatic reason for having non-short-circuit versions.
Original answer:
How would you propose &
(or |
) be a short-circuited operator? With &&
and ||
, it makes sense because you're dealing with boolean conditions: They can be true or false, there are no shades of grey. But &
and |
deal with bits, not booleans. The result is a number. I mean, I guess &
could not evaluate the right-hand side if the left-hand side were 0
, and similarly |
could not evaluate it if the left-hand side were all-bits-on for whatever the type was, but I don't see much point to making the one edge case of each operator significant (as compared to the 254 or more other cases).