Reputation: 88
&&
is supposed to have higher precedence than ||
:
int a = 10;
System.out.println(a==10 || --a==9 && a==8);
System.out.println(a);
this prints true, and 10. It seems that it checks only the first part and if its true the second never executes.
If I do a==9
then the second part seems to evaluate and prints 9. Can someone explain why this is happening? Isn't &&
supposed to evaluate first?
Edit: I see it. a==10 || --a==9 && a==8
transforms into (a==10) || (a==9 && a==8)
So if the first one evaluates to true it short circuits. Thank you for your help guys.
Upvotes: 4
Views: 307
Reputation: 4222
If you evaluate (a==10) || (b == 9)
(which is an OR
operation),
if the first clause is true
, then the entire expression must be true
(because it's OR) and the second clause will not be executed for reasons of optimization.
Code is executed from left to right, so you'll hit the first TRUE
therefore your entire statement will be TRUE
, and the remainder of your statement will not be executed
If your first clause is false
, then only will the second clause be evaluated.
If you use (a==10) | (b == 9)
both clauses will be evaluated.
If you want to be certain of the precedence of your operators, you should use brackets
Upvotes: 3
Reputation: 191
|| and && are short circuit operators they don't evaluate the right hand side expression
if the left hand side is true.
So (--a) is never executed as (a==10) left hand side is true
Therefore the value of a remains same.
**& and | operators that always evaluate both sides.
Upvotes: 0
Reputation: 7812
It's useful to look at expressions as trees.
a==10 || --a==9 && a==8
In this example, the top of the tree is an OR. The left branch is an EQUALS, and the right branch is an AND whose left and right branch are both EQUALS.
Since I'm awful at graphics, it would look something like:
OR
/ \-----
= \
/ \ AND
a 10 / \
= =
/ \ / \
--a 9 a 8
The "precedence" that you're talking about, orders this tree. But it doesn't necessarily change execution order. Because in this case, this is true if the first branch is true, so no need to check the second branch.
Upvotes: 3
Reputation: 1900
It doesn't have anything to do with higher precedence in this case. Look up lazy evaluation. The operation will be evaluated from left to right and will find that a==10
is true and stop there.
Look at the comments in http://introcs.cs.princeton.edu/java/11precedence/ under order of evaluation
Upvotes: 2
Reputation: 20455
System.out.println(a==10 || --a==9 && a==8);
equal to
System.out.println((a==10) || (((--a)==9) && (a==8)));
Java evaluates ||
first. Find out that left part (a==10) is true
and derive that no mater what is in right part result anyway will be true
PS: it is common trick to write
if(obj != null && obj.isSomething) { ... }
to prevent NPE
Upvotes: 4