Search code examples
javaoperator-precedence

How does Java process the expression x = x - (x = x - 1)?


I just tested the following code:

int x = 90;

x = x - (x = x - 1);
System.out.print(x);

It prints 1.

As far as I understand, things go in the following order:

  1. x - 1 is computed and stored to a temporary variable in memory.
  2. x is assigned the result from the temporary variable from item 1.
  3. Then x - the new value of x is calculated.
  4. The result is assigned to x;

I don't understand why x from which we subtract the result of item 2 still has initial value after item 2. What am I missing?


Solution

  • From https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

    All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left.

    You are doing 90 - (90 - 1) => 1

    It's important to not confuse precedence with order of evaluation. They are related but not the same.


    EDIT

    As @ruakh points out, the JLS spec put it differently to the tutorial above.

    http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15‌​.7.

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

    If the operator is a compound-assignment operator (§15.26.2), then evaluation of the left-hand operand includes both remembering the variable that the left-hand operand denotes and fetching and saving that variable's value for use in the implied binary operation.

    If evaluation of the left-hand operand of a binary operator completes abruptly, no part of the right-hand operand appears to have been evaluated.

    Rather than say the assignment is evaluated right to left, it treats assignment as first a store of the variable to be updated, then an evaluation of the value and finally an assignment.