如何评估A * = B * = A * = B?

tar*_*gul 5 java operators compound-assignment order-of-execution

public static void main(String[] args) {
    int A=5;
    int B=2;

    A *= B*= A *= B ;

    System.out.println(A);
    System.out.println(B);
}
Run Code Online (Sandbox Code Playgroud)

当我在纸上计算出这个问题时,我发现了A=200 B=20,但是当我写下它以使其黯然失色时,它表明A=100 B=20

您能在纸上解释解决方案吗?

我试图自己解决Eclipse中的问题。

我们该如何解决?

khe*_*ood 5

从开始A=5B=2

A变为A * B * A * B,即为100, B变为B * A * B,即为20。


更详细地:

A *= B *= A *= B
Run Code Online (Sandbox Code Playgroud)

A = A * (B = B * (A = A * B)) 
Run Code Online (Sandbox Code Playgroud)

决定解决

A = 5 * (B = 2 * (A = 5 * 2))
Run Code Online (Sandbox Code Playgroud)

意思是

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
Run Code Online (Sandbox Code Playgroud)


rge*_*man 5

这与在运算符顺序(优先级)之前进行的操作数评估有关。

在执行运算符之前,对操作数进行求值,在 Java 中总是按从左到右的顺序进行。

最左边的A被评估为5,然后最左边的B2,然后第二个A5,第二个B也是2。这些值被保存以供以后计算。

JLS,第15.26.2,用评价化合物赋值运算符的程序的交易。

如果左操作数表达式不是数组访问表达式,则:

  • 首先,评估左边的操作数以产生一个变量。如果这个评估突然完成,那么赋值表达式也会因为同样的原因突然完成;不计算右侧操作数,也不进行赋值。

  • 否则,保存左侧操作数的值,然后评估右侧操作数。如果此评估突然完成,则赋值表达式会出于相同的原因突然完成,并且不会发生赋值。

  • 否则,左侧变量的保存值和右侧操作数的值用于执行复合赋值运算符指示的二元运算。如果此操作突然完成,则赋值表达式会出于同样的原因突然完成,并且不会发生赋值。

  • 否则,二元运算的结果被转换为左侧变量的类型,经过值集转换(第 5.1.13 节)到适当的标准值集(不是扩展指数值集),结果转换的结果存储到变量中。

(粗体强调我的)

然后执行运算符,*=具有右结合性。这意味着操作从右到左进行。最右边的A *= B被执行,分配10A。中间B *= A被执行,赋值20B。但是,A *= B执行最左边的时候,保存的A还在 -- 5。当乘以 时20100分配给A

A *= B*= A *= B;  // A is now 100
Run Code Online (Sandbox Code Playgroud)

如果我们将其分解为 3 个语句,那么您将得到预期的200,因为A将作为最后一条语句的一部分再次评估 as 10,而不是5,因为保存的值为Anow 10

A *= B;
B *= A;
A *= B;  // A is now 200
Run Code Online (Sandbox Code Playgroud)