简体   繁体   English

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

[英]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. 它打印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. 计算x - 1并将其存储到存储器中的临时变量。
  2. x is assigned the result from the temporary variable from item 1. x从项目1的临时变量中分配结果。
  3. Then x - the new value of x is calculated. 然后x - the new value of x计算x - the new value of x
  4. The result is assigned to x ; 结果分配给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? 我不明白为什么从中减去项目2的结果的x在第2项之后仍然具有初始值。我缺少什么?

From https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html 来自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 你正在做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. 正如@ruakh指出的那样,JLS规范对上面的教程有所不同。

http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15 ‌​.7. 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. 如果运算符是复合赋值运算符(第15.26.2节),则对左侧操作数的计算包括记住左侧操作数表示的变量并获取并保存该变量的值以用于隐含的二进制操作。

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. 它不是说从右到左评估赋值,而是将赋值视为首先要更新的变量的存储,然后是值的评估,最后是赋值。

We start with: 我们从:

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

The first assignment operator = has low precedence, so the right side is evaluated first. 第一个赋值运算符=具有低优先级,因此首先计算右侧。

The right side of x = x - (x = x - 1) is x - b where b is (x = x - 1) x = x - (x = x - 1)的右边是x - b,其中b是(x = x - 1)

This right side is evaluated left to right, so it becomes 90 - b 这个右侧从左到右进行评估,因此它变为90-b

Then b, which is (x = x - 1), is evaluated. 然后评估b,即(x = x-1)。 Once again the assignment operator has lowest precedence, so it becomes (x = 90 - 1) or (x = 89) 赋值运算符再次具有最低优先级,因此它变为(x = 90 - 1)或(x = 89)

Substituting back, we have 90 - (x = 89) which is 90 - 89 which is 1. Finally, the first assignment operator is evaluated and x becomes 1. You'll notice that the other assignment operator (x = 89) had no effect on the overall operation. 替换回来,我们有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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM