Why is the output different in case of &&, &, ||?
Here is the code segments
Can you explain why outputs are varying
1)
public static ShortCkt {
public static void main(String args[]) {
int i = 0;
boolean t = true;
boolean f = false, b;
b = (t && ((i++) == 0));
b = (f && ((i+=2) > 0));
System.out.println(i);
}
}
output in this case is 1
2)
public static ShortCkt {
public static void main(String args[]) {
int i = 0;
boolean t = true;
boolean f = false, b;
b = (t & ((i++) == 0));
b = (f & ((i+=2) > 0));
Syste开发者_StackOverflowm.out.println(i);
}
}
output in this case is 3
3)
public static ShortCkt {
public static void main(String args[]) {
int i = 0;
boolean t = true;
boolean f = false, b;
b = (t || ((i++) == 0));
b = (f || ((i+=2) > 0));
System.out.println(i);
}
}
output in this case is 2
4)
public static ShortCkt {
public static void main(String args[]) {
int i = 0;
boolean t = true;
boolean f = false, b;
b = (t | ((i++) == 0));
b = (f | ((i+=2) > 0));
System.out.println(i);
}
}
output in this case is 3
Why is the output different in case of &&, &, || ?
Just as in C/C++ &&
is evaluated "lazily" while &
is not.
If a
is false then a && b
will return false without even evaluating b
.
Same goes for a || b
: If the first operand, a
is true, the whole expression is true and the second operand, b
is never evaluated. For a | b
however, both a
and b
will be evaluated.
This has consequences if the operand that's not being evaluated when using &&
(or ||
) has side effects, as in your examples.
Side note: Few java-programmers know that ^
(xor) works for booleans as well. (A ^^
version does not exist simply because it would be redundant.)
There are 4 boolean
binary operators that we're concerned with here:
&&
is the conditional and operator&
is the logical and operator
||
is the conditional or operator|
is the logical or operator
Here's the key point:
- "conditional" means it short-circuits: it does not evaluate the right operand if it will not affect the result of the operation
- "logical" does not short-circuit: it evaluates both operands, left first, then right.
- The result of "and" is
true
only if both operands aretrue
- If the left operand is
false
, the result isfalse
regardless of right operand
- If the left operand is
- The result of "or" is
true
only if at least one operand istrue
- If the left operand is
true
, the result istrue
regardless of right operand
- If the left operand is
In other words, assuming no exception etc:
&
and|
always evaluate both operands&&
and||
evaluate the right operand conditionally; the right operand is evaluated only if its value could affect the result of the binary operation. That means that the right operand is NOT evaluated when:- The left operand of
&&
evaluates tofalse
- (because no matter what the right operand evaluates to, the entire expression is
false
)
- (because no matter what the right operand evaluates to, the entire expression is
- The left operand of
||
evaluates totrue
- (because no matter what the right operand evaluates to, the entire expression is
true
)
- (because no matter what the right operand evaluates to, the entire expression is
- The left operand of
References
- JLS 15.22.2 Boolean Logical Operators
&
,^
, and|
- For
&
, the result value istrue
if both operand values aretrue
; otherwise, the result isfalse
. - For
|
, the result value isfalse
if both operand values arefalse
; otherwise, the result istrue
.
- For
- JLS 15.23 Conditional-And Operator
&&
- The
&&
operator is like&
, but evaluates its right-hand operand only if the value of its left-hand operand istrue
.
- The
- JLS 15.24 15.24 Conditional-Or Operator
||
- The
||
operator is like|
, but evaluates its right-hand operand only if the value of its left-hand operand isfalse
.
- The
See also
- JLS 15.22.1 Integer Bitwise Operators
&
,^
, and|
Related questions
- What’s the difference between
|
and||
in Java? - Do
&=
and|=
short-circuit in Java? (NO!) - Shortcut "or-assignment" (
|=
) operator in Java - Why doesn’t Java have
&&=
or||=
?
&&
and ||
are the logical AND and OR operators, they always result in a boolean
expression. &
and |
are bitwise AND and OR operators, they do a bitwise comparison of each side. For more information about what those operators do, see this link
This is because && and || are logical operators which a "short circut mechanism". If you use || and the first expression evaluates to true, the second won't be evaluated and hence i will not be udated. & and | are bitwise operators which do bit calculations on the input. These do not have short circut and hence the entire expression is evaluated no matter what.
The &
and |
operators are bitwise, and thus must have both sides of the expression evaluated before the operator can be used, so in cases 2 and 4 both sides of the operator are always evaluated.
The difference between cases 1 and 3 is based on short-circuit logic.
In case 1 the &&
operator in the second expression short-circuits as false
on the first false
, causing the second half of the expression not to be evaluated.
In case 3 the false
in the first half of the second expression leads to the evaluation of the second half of the expression, incrementing i
. false || expr
can only be false
if expr
is also false (so it must be evaluated).
精彩评论