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

时间:2019-08-22 22:27:25

标签: java operators order-of-execution compound-assignment

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,但是当我写下来使其日蚀时,却显示了A=100 B=20

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

我试图独自在Eclipse中解决问题。

我们如何解决?

2 个答案:

答案 0 :(得分:5)

A=5B=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

答案 1 :(得分:4)

这与运算符在运算符顺序(优先级)之前发生的求值有关。

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

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

JLS, Section 15.26.2处理评估复合赋值运算符的过程。

  

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

     
      
  • 首先,对左侧操作数求值以产生一个变量。如果该评估突然完成,则赋值表达式由于相同的原因而突然完成;右边的操作数不会被评估,也不会发生赋值。

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

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

  •   
  • 否则,将二进制运算的结果转换为左侧变量的类型,然后将值集转换(第5.1.13节)转换为适当的标准值集(而不是扩展指数值)设置),然后将转换结果存储到变量中。

  •   

(加粗强调)

然后执行操作符,其中*=具有右关联性。这意味着操作从右向左进行。执行最右边的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,而不是{{ 1}},因为5的保存值现在为A

10