赋值语句左侧的java后缀增量运算符的语义是什么,为什么它们与右侧不同?

  • 本文关键字:是什么 后缀 java 赋值语句 语义 运算符 java
  • 更新时间 :
  • 英文 :


我正在处理一个leetcode问题[1],注意到一些吸引我眼球的东西。

当我把一行代码写为:

nums[i] = nums[(i++)+count];

我通过了所有的测试,我的答案被接受了。然而,如果我将同一行更改为:

nums[i++] = nums[i+count];

我得到一个ArrayOutOfBounds异常。为什么会这样?

这是完整的代码:

public void moveZeroes(int[] nums) {
    int count = 0, i = 0;
    while(i+count < nums.length){
        if(nums[i+count] == 0)
            count++;
        else
            nums[i] = nums[(i++)+count];
    }
    for(;i<nums.length; i++)
        nums[i] = 0;
}

[1]https://leetcode.com/problems/move-zeroes/

答案在JLS 15.26.1中。基本上,这是情况下的事情顺序

nums[i++] = nums[i+count];
  • nums被评估(作为左侧的一部分)
  • 对CCD_ 2进行评估以找到索引;结果是i的原始值,但i随后递增
  • 在这一点上,我们已经评估了要分配给哪个数组元素
  • 评估nums(作为右侧的一部分)
  • 对CCD_ 6进行评价;注意,这使用了i已经递增的值,这就是为什么您会得到一个异常
  • 我们现在知道要获取哪个数组元素
  • 获取该元素的值
  • 将值分配给我们之前确定的LHS元素

重要的部分是赋值运算符的左操作数在右操作数上的表达式之前求值。因此,在左操作数中计算数组索引表达式时的副作用会影响右操作数的计算。

在第一个示例中,i在该迭代中使用完毕后递增。

nums[(i++)+count];

表示在评估CCD_ 10的等价物之后将CCD_。

在第二个示例中,inums[ i +count];之前递增。

nums[i++]

意味着在评估CCD_ 14的等价物之后将CCD_。

当代码到达nums[ i + count];时,i已经递增。在i + count等于nums.length的情况下,这会导致ArrayOutOfBounds异常。

最新更新