A *= B *= A *= B 是怎么求值的?
How is A *= B *= A *= B evaluated?
public static void main(String[] args) {
int A=5;
int B=2;
A *= B*= A *= B ;
System.out.println(A);
System.out.println(B);
}
当我在纸上计算这个问题时我发现A=200 B=20
,但是当我把它写到eclipse时它显示A=100 B=20
能不能像纸上解一样解释一下解法?
我尝试在 Eclipse 中自己解决。
如何解决?
从 A=5
、B=2
开始
A
变为 A * B * A * B
,即 100,并且
B
变为 B * A * B
,即 20.
更详细:
A *= B *= A *= B
是
A = A * (B = B * (A = A * B))
解析为
A = 5 * (B = 2 * (A = 5 * 2))
这意味着
A = 5 * (B = 2 * (A = 10)) // set A to 10
A = 5 * (B = 2 * 10)
A = 5 * (B = 20) // set B to 20
A = 5 * 20
A = 100 // set A to 100
这与在运算符顺序(优先级)之前发生的操作数评估有关。
在执行运算符之前,对操作数求值,在 Java 中,操作数总是按从左到右的顺序进行。
最左边的A
被计算为5
,那么最左边的B
就是2
,那么第二个A
就是5
第二个 B
也是 2
。这些值被保存以供以后计算。
JLS, Section 15.26.2 处理复合赋值运算符的计算过程。
If the left-hand operand expression is not an array access expression, then:
First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
(大胆强调我的)
然后执行运算符,*=
具有右结合性。这意味着操作从右到左进行。最右边的A *= B
被执行,将10
赋值给A
。中间的B *= A
被执行,将20
赋值给B
。但是,最左边的A *= B
执行时,A
的saved值还在——5
。当乘以20
时,100
赋值给A
。
A *= B*= A *= B; // A is now 100
如果我们将其分解为 3 个语句,那么您将得到预期的 200
,因为 A
将作为最后一个语句的一部分再次计算为 10
,而不是5
,因为 A
的保存值现在是 10
。
A *= B;
B *= A;
A *= B; // A is now 200
public static void main(String[] args) {
int A=5;
int B=2;
A *= B*= A *= B ;
System.out.println(A);
System.out.println(B);
}
当我在纸上计算这个问题时我发现A=200 B=20
,但是当我把它写到eclipse时它显示A=100 B=20
能不能像纸上解一样解释一下解法?
我尝试在 Eclipse 中自己解决。
如何解决?
从 A=5
、B=2
A
变为 A * B * A * B
,即 100,并且
B
变为 B * A * B
,即 20.
更详细:
A *= B *= A *= B
是
A = A * (B = B * (A = A * B))
解析为
A = 5 * (B = 2 * (A = 5 * 2))
这意味着
A = 5 * (B = 2 * (A = 10)) // set A to 10
A = 5 * (B = 2 * 10)
A = 5 * (B = 20) // set B to 20
A = 5 * 20
A = 100 // set A to 100
这与在运算符顺序(优先级)之前发生的操作数评估有关。
在执行运算符之前,对操作数求值,在 Java 中,操作数总是按从左到右的顺序进行。
最左边的A
被计算为5
,那么最左边的B
就是2
,那么第二个A
就是5
第二个 B
也是 2
。这些值被保存以供以后计算。
JLS, Section 15.26.2 处理复合赋值运算符的计算过程。
If the left-hand operand expression is not an array access expression, then:
First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
(大胆强调我的)
然后执行运算符,*=
具有右结合性。这意味着操作从右到左进行。最右边的A *= B
被执行,将10
赋值给A
。中间的B *= A
被执行,将20
赋值给B
。但是,最左边的A *= B
执行时,A
的saved值还在——5
。当乘以20
时,100
赋值给A
。
A *= B*= A *= B; // A is now 100
如果我们将其分解为 3 个语句,那么您将得到预期的 200
,因为 A
将作为最后一个语句的一部分再次计算为 10
,而不是5
,因为 A
的保存值现在是 10
。
A *= B;
B *= A;
A *= B; // A is now 200