Java,"a [1]*= a [1] = b [n + 1]"没有按预期工作?

Hex*_*own 4 java multiplication variable-assignment assignment-operator

所以正如标题所示,我有一个使用临时数组的函数,我想从另一个数组中写入一个值,然后将这两个值与它自身相乘.

例:

float[] a = {0, 0}

a[0] *= a[0] = b[n    ];
a[1] *= a[1] = b[n + 1];
Run Code Online (Sandbox Code Playgroud)

我希望上面会做到以下几点:

a[0] = b[n    ];
a[0] *= a[0]; //(aka: a[0] = a[0] * a[0])

a[1] = b[n + 1];
a[1] *= a[1];
Run Code Online (Sandbox Code Playgroud)

虽然这种行为似乎并没有发生.相反,它似乎只是乘以"a"中的原始值与"b"中保存的任何值相乘,如下所示:

a[0] = a[0] * b[n    ];
a[1] = a[1] * b[n + 1];
Run Code Online (Sandbox Code Playgroud)

总是我的理解是,首先评估"="之后的任何内容,如下所示:

float a, b;
a = b = 5;
//"a" and "b" both equal "5" now.
Run Code Online (Sandbox Code Playgroud)

既然如此,是不是表明我原来的例子应该有效?

任何人都可以解释发生了什么以及为什么这段代码无法正常工作?

Axe*_*xel 7

我认为到目前为止答案是不正确的.最重要的是复合表达式的评估a *= b.简而言之,左手侧的值在右手侧之前计算.来自JLS(强调我的):

在运行时,表达式以两种方式之一进行评估.

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

首先,评估左侧操作数以产生变量.如果此评估突然完成,则赋值表达式出于同样的原因突然完成; 不评估右侧操作数,也不进行赋值.

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

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

否则,二进制操作的结果将转换为左侧变量的类型,经过值集转换(第5.113节)到相应的标准值集(不是扩展指数值集),结果转换的内容存储在变量中.

在你的例子中:

a[0] *= a[0] = b[n    ];
Run Code Online (Sandbox Code Playgroud)
  1. 如果a[0]计算并存储了值tmp
  2. a[0] = b[n]被评估,给出值b[n](并改变a[0]to 的值b[n])
  3. tmp * a[0] 计算
  4. 最后一步的结果被分配给 a[0]

所以,你得到的是有效的a[0] *= b[n].

编辑:关于从右到左评估任务的混淆:我没有找到JLS中使用的术语,恕我直言它不正确(尽管它在Java教程中使用).它被称为正确 - **associative*assThe JLS说这是关于任务的:

有12个赋值运算符; 所有这些都是语法上的右关联(他们从右到左分组).因此,a = b = c表示a =(b = c),它将c的值赋给b,然后将b的值赋给a.