There are a couple of differences between the &
and &&
operators. The same differences apply to |
and ||
. The most important thing to keep in mind is that &&
is a logical operator that only applies to boolean operands, while &
is a bitwise operator that applies to integer types as well as booleans.
With a logical operation, you can do short circuiting because in certain cases (like the first operand of &&
being false
, or the first operand of ||
being true
), you do not need to evaluate the rest of the expression. This is very useful for doing things like checking for null
before accessing a filed or method, and checking for potential zeros before dividing by them. For a complex expression, each part of the expression is evaluated recursively in the same manner. For example, in the following case:
(7 == 8) || ((1 == 3) && (4 == 4))
Only the emphasized portions will evaluated. To compute the ||
, first check if 7 == 8
is true
. If it were, the right hand side would be skipped entirely. The right hand side only checks if 1 == 3
is false
. Since it is, 4 == 4
does not need to be checked, and the whole expression evaluates to false
. If the left hand side were true
, e.g. 7 == 7
instead of 7 == 8
, the entire right hand side would be skipped because the whole ||
expression would be true
regardless.
With a bitwise operation, you need to evaluate all the operands because you are really just combining the bits. Booleans are effectively a one-bit integer in Java (regardless of how the internals work out), and it is just a coincidence that you can do short circuiting for bitwise operators in that one special case. The reason that you can not short-circuit a general integer &
or |
operation is that some bits may be on and some may be off in either operand. Something like 1 & 2
yields zero, but you have no way of knowing that without evaluating both operands.