【问题标题】:How is A *= B *= A *= B evaluated?如何评估 A *= B *= A *= B?
【发布时间】:2019-12-28 06:33:41
【问题描述】:
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 中自己解决。

我们如何解决它?

【问题讨论】:

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    JLS, Section 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 现在是 10

    A *= B;
    B *= A;
    A *= B;  // A is now 200
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      • 1970-01-01
      • 2014-03-29
      • 2021-10-06
      • 1970-01-01
      相关资源
      最近更新 更多