AbdelRahmane AbdelRahmane - 1 month ago 15
Java Question

Java confusing example about '&&' and '||' precedence

I was testing the precedence between && and || and i had an example that confuses me about that.
So we know that in java : && has higher operator precedence than the operator ||.

So if we have those 3 expressions :

//expr1 = true , expr2 = false; expr3 = false;

if(expr1 || expr2 && expr3);


should be evaluated as :

if(expr1 || (expr2 && expr3));


So :
expr2 should be evaluated before expr1

However this example :

int a1 = 10;
int a2 = 20;
System.out.println(a1 < a2 || ++a1 > a2 && ++a2 < a1);
System.out.println(a1);
System.out.println(a2);


Outputs:

true
10
20


that prove that only
a1 < a2
is evaluated.

Can you please explain to me why it gives those results!

Answer

The expression is short-circuiting. From the link:

when the first argument of the AND function evaluates to false, the overall value must be false; and when the first argument of the OR function evaluates to true, the overall value must be true.

It sees that the rest of the condition doesn't matter because one of the operands of || is already true (10 < 20). If one of the operands is true, then no matter what the rest of the condition is, it's true.

You may use bitwise & and | to prevent this.


But, the ( expr2 && expr3 ) should be evaluated before expr1, no ?

Precedence only changes the expression's structure, not evaluation order. It still will be evaluated left to right. Even if you explicitly add grouping around the && operands, it will start left to right and short-circuit. Consider this:

if(false || false || true && (false || true) || false)
     1         2       3        4        5        6

Expressions 1 and 2 are evaluated first and will keep on going as they are false. It will then advance to expression 3, and will see that it is true. Thus, it continues by evaluating the parentheses. Since 4 is false, it won't short-circuit and will keep on going. 5 is true so inside the parentheses is true. True AND true is true, and true OR false is true (and short-circuits). Finally, the whole condition is true.

Notice that the condition was evaluated left to right, and order was not changed.