JAVA : Why does the following infinite loop terminate without any error / exception
本问题已经有最佳答案,请猛点这里访问。
我在处理Eclipse中的一些东西时,令我惊讶的是,我发现运行时的这段代码被终止,没有任何错误/异常
1 2 3 4 5 6 7 | public class Test { public static void main(String[] args) { for(int i = 2; i > 0; i++){ int c = 0; } } } |
当他的代码继续执行时
1 2 3 4 5 6 7 8 |
号
即使两者都应该是无限循环,永远运行。对于第一个代码片段为何被终止,我是否遗漏了一些内容?
首先,这两个代码段都不是无限循环,因为当
测试您的第一个代码片段,在循环前后添加
1 2 | 1486539220248 1486539221124 |
也就是说,它在不到1秒的时间内运行。
稍微改变循环:
1 2 3 4 5 6 7 |
号
我得到了
1 2 3 | 1486539319309 2147483647 1486539319344 |
如您所见,从
添加到循环中的打印越多,终止所需的时间就越多。例如:
1 2 3 4 5 6 7 |
。
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 1486539560318 100000000 200000000 300000000 400000000 500000000 600000000 700000000 800000000 900000000 1000000000 1100000000 1200000000 1300000000 1400000000 1500000000 1600000000 1700000000 1800000000 1900000000 2000000000 2100000000 1486539563232 |
现在花了3秒钟。
重点是:这个循环没有任何明显的副作用。
因此,可以假设编译器正在优化整个循环。另一方面,javac并不以进行大量优化而出名。因此:让我们看看会发生什么:
javap -c Test
...
public static void main(java.lang.String[]);
号
1 2 3 4 5 6 7 8 9 | 0: iconst_2 1: istore_1 2: iload_1 3: ifle 14 6: iconst_0 7: istore_2 8: iinc 1, 1 11: goto 2 14: return |
。
显然:循环还在那里。所以真正的问题是:你的循环在某个时刻由于int溢出而停止;而你的程序的第一个版本只是更快地到达那一点(out.println()是一个非常昂贵的操作;与单纯的数字相加相比)