问题
As I was reading a colleague's Java code, I stumbled upon an army of if/else statements. In these statements, several &&
and ||
operators were fighting each other without any help from parenthesis. I simplified the statements into:
if (true || true && false)
return true;
else
return false;
What do you think the result would be? Honestly, I thought it would be false
, but it seems short-circuiting doesn't work like I expected. In this case, the result is true
. The short-circuit mechanism seems to consider the whole expression as true
when it finds true
immediately followed by ||
.
But in the reversed expression, what is the result?
if (false && true || true)
return true;
else
return false;
If we follow the same logic, it should be false. the first boolean is false
and it is immediately followed by &&
, but the result is true
, once again. This makes sense to me, but it seems incompatible with our previous experiment.
So here's my theory:
If we find a true
followed by ||
, then it is true
, no matter what might comes next, even if there is a long list of other logical operators coming after. But if we find a false
followed by &&
, it only short-circuits the next element, not the whole statement.
And here's my question:
Am I right? It seems a bit silly to me. Is true
stronger than false
?
回答1:
It's simply because
if (false && true || true)
is equivalent to (&&
has a higher precedence)
if ((false && true) || true)
which is
if (false || true)
which is... true
.
Note: In the expression true || true && false
, the part true && false
is called a dead code because it doesn't affect the final result of the evaluation, since true || anything
is always true
.
It is worth mentioning that there exist &
and |
operators that can be applied to booleans, they are much like &&
and ||
except that they don't short circuit, meaning that if you have the following expression:
if (someMethod() & anotherMethod())
and someMethod
returns false
, anotherMethod
will still be reached! But the if
won't be executed because the final result will be evaluated to false
.
回答2:
The &&
has higher operation precedence over the ||
, thus it wins.
回答3:
According to Java tutorials &&
has higher precedence over ||
So your true || true && false
would be evaluated as true || (true && false)
And your false && true || true
would be evaluated as (false && true) || true
Resulting in an output of true
in both case.
回答4:
for &&
:
false && ... => false
for ||
:
true || ... => true.
And precedence for &&
is higher than ||
.
See more: Operator Precedence in Java
回答5:
Because of the precedence of &&
on ||
, (true || true && false)
this will be evaluated as (true || (true && false)) -> (true || (false)) -> true
See the precedences rules: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
回答6:
I see what you were trying to do, but before operating on parentheses it's good to have the language's specification handy. I've known a few programmers who have gone so far as to keep the important bits, like operator precedence, on their walls.
The second part is to know whether your alterations are going to make any sense to the other people in your workplace; if removing parentheses compromises the meaning of an operation to someone else working on the code, then it could ultimately be detrimental.
The optimizer will generally take care of it for you, so when in doubt, leave them in there.
来源:https://stackoverflow.com/questions/30033035/java-logical-operator-short-circuit-mechanism