关于java:Post Increment Infinite loop i + = i ++;

Post Increment Infinite loop i += i++;

本问题已经有最佳答案,请猛点这里访问。

我不明白为什么这个后增量方程没有增加。我本以为在+=操作之后,值会增加1,然后第二次我会得到1的值。但是输出是一个无限循环,0为零。有人能解释为什么‘我’不增加吗?

1
2
3
4
5
6
int i = 0;
for(; ; ) {
  if ( i >= 10) break;
  i += i++;
}
System.out.println(i);


让我们检查一下i += i++;

i++表示读取i的值,然后递增i

i += x是指对i进行评价,再对x进行评价,加上2,将结果放入i中。

所以,发生的是:

  • i得到评价,为0
  • 评估i++。返回0i的值设置为1
  • i += i++现在是i = 0 + 0
  • i = 0

在读取值之前,尝试使用++i获取递增的结果。


虽然@njzk2的答案是正确的,但指出其正确原因是很有用的。

还有其他的可能性——例如,为什么Java在赋值之后不执行后增量运算符?(回答:因为这不是Java语言设计者选择的)

在Java语言规范部分1523.2中指定了复合赋值的评价顺序(如EDCOX1(18))。我将引用它是如何定义Java 8的:

  • First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression
    completes abruptly for the same reason; the right-hand operand is not
    evaluated and no assignment occurs.

  • Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes
    abruptly, then the assignment expression completes abruptly for the
    same reason and no assignment occurs.

  • Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation
    indicated by the compound assignment operator. If this operation
    completes abruptly, then the assignment expression completes abruptly
    for the same reason and no assignment occurs.

  • Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion
    (§5.1.13) to the appropriate standard value set (not an
    extended-exponent value set), and the result of the conversion is
    stored into the variable.

最重要的是,首先保存左侧表达式的值,然后完全计算右侧表达式的值,然后将复合运算的结果存储在左侧的变量中。


你进入无限循环并不奇怪。

1
2
3
4
5
6
7
8
9
10
11
class Demo{
  public static void main(String[] args){
    int i = 0;
    for( ; ; ) {
        if (i >= 10)
            break;
        i = i+i++;
        System.out.println(i);
    }
  }
}

假设上面的代码,我刚刚用编译器将替换的增量替换了您的行。

现在,最初i=0;所以

1
i = i+i++

结果i=0+0/,现在i为1

但最后你又让我等于0!

因此无穷大…