Java 如何处理表达式 x = x - (x = x - 1)?

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

我刚刚测试了以下代码:

int x = 90;

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

它打印 1。

据我了解,事情按以下顺序进行:

  1. x - 1 被计算并存储到内存中的一个临时变量中。
  2. x 被赋值为项目 1 的临时变量的结果。
  3. 然后计算出x - the new value of x
  4. 结果赋值给x;

我不明白为什么我们减去第2项的结果的x在第2项之后仍然有初始值。我错过了什么?

来自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.

你正在做 90 - (90 - 1) => 1

重要的是不要将优先级与评估顺序混淆。它们是相关但不相同的。


编辑

正如@ruakh 指出的那样,JLS 规范与上面的教程有所不同。

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.

不是说赋值是从右到左计算的,而是将赋值视为首先要更新的变量的存储,然后是值的计算,最后是赋值。

我们从:

开始
int x = 90;
x = x - (x = x - 1);

第一个赋值运算符 = 的优先级较低,因此首先计算右侧。

x = x - (x = x - 1) 的右边是 x - b 其中 b 是 (x = x - 1)

这个右边是从左到右计算的,所以它变成 90 - b

然后计算 b,即 (x = x - 1)。赋值运算符再次具有最低优先级,因此它变为 (x = 90 - 1) 或 (x = 89)

代回,我们有 90 - (x = 89) 即 90 - 89 即 1。最后,第一个赋值运算符被求值并且 x 变为 1。你会注意到另一个赋值运算符 (x = 89) 对整体运行没有影响。

   int x = 90;
   x = x - (x = x - 1);
   System.out.print(x);`
Here
x = 90 Goes in two section in your code.
First x=90 - , Second  (x=90-1);
Then x=90  - , x = 89 
Then x= 90 - 89
       System.out.Print(x);
that is x=1;