2 Answers
2

The single & will check both conditions always. The double && will stop after the first condition if it evaluates to false. Using two is a way of "short circuiting" the condition check if you truly only need 1 condition of 2 to be true or false.

An example could be:

if (myString != null && myString.equals("testing"))

If myString is null, the first condition would fail and it would not bother to check the value of it. This is one way you can avoid null pointers.

with & and ¦ both operands are always evaluated

with && and ¦¦ the second operand is only evaluated when it is necessary

Here's a link to a page with a pretty good explanation of how to use these.

Absolutely correct. Use "&", "|" and friends if you want to twiddle bits (e.g. for bitmapped flags). Use "&&" or "||" if you want to evaluate "if this, then that" conditionals. An important consideration using the latter is "short circuit evaluation", meaning evaluation will STOP the moment it encounters a definite "true" or "false".
–
paulsm4Jan 1 '12 at 3:44

The other answers are correct to an extent, but don't explain the whole thing.

First off, the doubled operators, && and ||, function sort of like nested if statements:

if (expression_a && expression_b) {
do_something;
}

is equivalent to

if (expression_a) {
if (expression_b) {
do_something;
}
}

In both cases, if expression_a evaluates to false then expression_b will not be evaluated -- a feature referred to as "short-circuiting". (The || case is similar but a hair more complicated.)

Additionally, in Java (but not in C/C++) the && and || operators apply only to boolean values -- you cannot use && or || on an int, eg.

The single operators, & and |, on the other hand, are relatively "pure" operators (commutative and associative with respect to themselves), with none of the "short-circuiting" of the double operators. Additionally, they can operate on any integer type -- boolean, char, byte, short, int, long. They perform a bit-by-bit operation -- bit N of the left operand is ANDed or ORed with bit N of the right operand to produce the Nth bit in a result value that is the same bit width as the two operands (after they are widened as appropriate for binary operators). In this regard, their operation with boolean is just the degenerate case (albeit one that is somewhat special-cased).

Normally, one would use only the doubled operators for combining boolean expressions in an if statement. There is no great harm in using the single operators if the boolean expressions involved are "safe" (cannot result in a null pointer exception, eg), but the doubled operators tend to be slightly more efficient and the short-circuiting is often desired (as in if (a != null && a.b == 5), eg), so it's generally wise to cultivate the habit of using the doubled forms. The only thing to beware of is that if you want the second expression to be evaluated (for it's side-effects), the doubled operator will not guarantee this happens.