Java中复合赋值运算符的运算顺序

Java中复合赋值运算符的运算顺序,java,Java,我最近在一次模拟考试中遇到了以下问题,我有点不明白为什么根据操作顺序给出的答案是25,25,以及我可能在给出详细原因的规范中遗漏了什么 public class Test { public static void main(String[] args) { int k = 1; int[] a = {1}; k += (k = 4) * (k + 2); a[0] += (a[0] = 4) * (a[0] + 2);

我最近在一次模拟考试中遇到了以下问题,我有点不明白为什么根据操作顺序给出的答案是25,25,以及我可能在给出详细原因的规范中遗漏了什么

public class Test {

    public static void main(String[] args) {
        int k = 1;
        int[] a = {1};
        k += (k = 4) * (k + 2);
        a[0] += (a[0] = 4) * (a[0] + 2);
        System.out.println(k + " , " + a[0]);
    }
}
只要看一下上面的第6行,我就替换了适当的值,并得到以下结果:

k = k + (k = 4) * (k + 2);
我首先计算圆括号,它表示k首先被赋值为4,然后被加到数字2,得到的总数是6。我是这样理解的:

k = k + 4 * 6;
现在这是让人困惑的地方。根据操作顺序,我得到以下结果,这将是正确的,给出前面的表达式:

k = k + 24;

在这一点上,我认为k应该是4,因为这是新的作业,但答案实际上是25,而不是28。显然复合运算符有一些我不理解的优先顺序,或者我的替换原则是不正确的。

在这个答案中,我只考虑<代码> k< /Cudio>情况,对于数组是相同的。

int k = 1;
k += (k = 4) * (k + 2);
// k += (k = 4) * (k + 2)
// 1 += (k = 4) * (k + 2)
// 1 +=    4    * (k + 2) with k = 4
// 1 +=    4    *   6     with k = 4
// k = 25
这里的技巧是:

  • k+=
    在进行计算之前捕获
    k
    的值<代码>+=称为。引用JLS的相关部分: 保存左侧操作数的值,然后计算右侧操作数的值

  • k=4
    返回指定的值,因此为4

这就是为什么您应该始终使用
final
变量,最左侧的
k
不会改变,因为您在右侧改变了它。你认为你用这种错综复杂的逻辑完成了什么?问题的第一句话:“我最近在一次模拟考试中遇到了以下问题……”。我决不会故意编写这些垃圾代码。告诉那些提出这类问题的人,这些问题愚蠢且不切实际。这些问题定义的是优先级,而不是执行顺序。例如,in
n=1;m=n+(n=2),m将等于3,而不是4。也就是说,仅仅因为
(n=2)
在括号中并不意味着您首先对其求值。我认为键的一部分可能与“……保存左操作数的值,然后对右操作数求值”重复。这是因为此求值发生在右操作数的任何其他顺序之前。这是一个“安全”的假设吗?我问这个问题的唯一原因是因为学习认证的很大一部分是能够正确地应用规则,而在这个过程中,规则可能是几个规则的子集。@BrianReindel是的,可以保证在评估右侧之前保存
k
的值。无论您如何使用右侧的
k
,它都将始终保持其先前的值,在本例中为1。