Search code examples
javalogical-operators

Evaluation order of Java operators && vs ||


I have this simple code block

int a = 10;
int b = 20;
int c = 30;
boolean result = a++ == 10 || b++ == 20 && c++ < 30;
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(result);

When I run this, the console is

11
20
30
true

This result tell me that only a++ == 10 is evaluated.

As I read from this https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html, operator && have higher priority than || and should be evaluated first. In this book OCA Java SE 8 Programmer I Certification Guide, at twist 2.4, a similar example give the answer that all the logical operands will be evaluated. && is evaluated first and || is the last.

But the result give me an assumption that the priority is just used to group operands and operators. From this a++ == 10 || b++ == 20 && c++ < 30 to this a++ == 10 || (b++ == 20 && c++ < 30) When expression is evaluated, it is short-circuited by the value true on the left of ||. So the expression on the right (the && operator) is not evaluated. Because if the operator && is evaluated first, the value of b and c will be increased but it does not.

Am I correct? Please help.


Solution

  • The tutorial page on operators only gives you an informal description of the operator precedence, when the java code is executed. The table shown on the page does not exists as such in the JLS. The execution/evaluation order depends on how the source code is parsed and how the parse tree is generated.

    A code fragment as a || b && c (in this example code) will be parsed as an Expression:

    Expression:
      LambdaExpression
      AssignmentExpression
    

    In this case, it's an AssignmentExpression:

    AssignmentExpression:
      ConditionalExpression
      Assignment
    

    In this case, it's a ConditionalExpression:

    ConditionalExpression:
      ConditionalOrExpression
      ConditionalOrExpression ? Expression : ConditionalExpression
      ConditionalOrExpression ? Expression : LambdaExpression
    

    In this case, it's a ConditionalOrExpression (the first line, not the one with the tenary operator):

    ConditionalOrExpression:
      ConditionalAndExpression
      ConditionalOrExpression || ConditionalAndExpression
    

    And here we will have it translated to the second line (ConditionalOrExpression || ConditionalAndExpression) as we have the "||" characters here (the actual || operator).

    The JLS specifies that the left operand of the || operator is evaluated first by 15.7.1. Evaluate Left-Hand Operand First:

    The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.

    It also specifies, that the || operator is "short-circuited", as defined in 15.24. Conditional-Or Operator ||:

    The conditional-or operator || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false.

    In total this means that the left operand is evaluated (a++ == 10, which will increase the variable a) and because this comparison results in true, the right operand will NOT be evaluated. So neither b++ nor c++ will be evaluated in any way.