我有以下代码示例。
int i = 1;
while(i != 0) {
i++;
}
我原本以为这个程序会一直运行下去,但实际上并没有。当我在 while 循环后打印变量时,输出了以下结果:
i value is 0.
请问有人能告诉我到底发生了什么吗?
int i = 1;
while(i != 0) {
i++;
}
我原本以为这个程序会一直运行下去,但实际上并没有。当我在 while 循环后打印变量时,输出了以下结果:
i value is 0.
请问有人能告诉我到底发生了什么吗?
我本以为这将会无限循环,但它并没有。
不会的。最终,该值会再次变为0。
具体来说,它的逻辑执行方式如下:
1
2
3
...
2,147,483,646
2,147,483,647
-2,147,483,648 // Integer overflow => wrapping
-2,147,483,647
...
-3
-2
-1
0
如果整数相加溢出,则结果是在某个足够大的二进制补码格式中表示的数学总和的低阶位。 如果发生溢出,则结果的符号与两个操作数值的数学总和的符号不同,然后循环将结束。
引用自JLS第15.18.2节:
如果整数相加溢出,则结果是在某个足够大的二进制补码格式中表示的数学总和的低阶位。 如果发生溢出,则结果的符号与两个操作数值的数学总和的符号不同。
此代码没有任何内存问题,因为它不执行任何分配 - 它只是在堆栈上完全递增一个局部变量。
现在这是否实际上做到了这一点是另一回事 - 如果JIT能够在不执行每次迭代的情况下找出行为,它可以将其优化掉 - 但这是一个实现细节。 重要的是理解行为背后的逻辑。
Int
是一个int
: 对于每个i
,如果i
是int
,那么i+1
也是int
。一个int
始终是32位,它永远不需要更大的容器。
最后,你的循环不是无限的。