这与在运算符顺序(优先级)之前进行的操作数评估有关。
在执行运算符之前,计算操作数,在 Java 中总是以从左到右的顺序进行。
最左边A
的被评估为5
,然后最左边B
的是2
,然后第二个A
是5
,第二个B
也是2
。保存这些值以供以后计算。
JLS第15.26.2 节处理评估复合赋值运算符的过程。
如果左侧操作数表达式不是数组访问表达式,则:
首先,评估左侧操作数以产生变量。如果这个求值突然完成,那么赋值表达式也会因为同样的原因而突然完成;不计算右侧操作数,也不发生赋值。
否则,将保存左侧操作数的值,然后计算右侧操作数。如果这个求值突然完成,那么赋值表达式也会因为同样的原因而突然完成并且没有赋值发生。
否则,左侧变量的保存值和右侧操作数的值用于执行复合赋值运算符指示的二元运算。如果此操作突然完成,则赋值表达式出于同样的原因突然完成并且不发生赋值。
否则,二元运算的结果将转换为左侧变量的类型,经过值集转换(第 5.1.13 节)到适当的标准值集(不是扩展指数值集),并将结果转换的存储到变量中。
(粗体强调我的)
然后执行运算符,*=
具有右关联性。这意味着操作从右到左进行。最右边A *= B
的被执行,分配10
给A
. 中间B *= A
被执行,分配20
给B
. 但是,当最左边A *= B
的执行时,保存的值A
仍然存在 - 5
。乘以 时20
,100
分配给A
。
A *= B*= A *= B; // A is now 100
如果我们将其分解为 3 个语句,那么您将得到预期的200
,因为A
将作为最后一个语句的一部分再次评估为10
,而不是5
,因为保存的值为A
now 10
。
A *= B;
B *= A;
A *= B; // A is now 200