For (; ;) vs. while (true)

标准 while(true)循环和 for(;;)循环的区别是什么?

在编译之后,是否存在或者两者都将被映射到同一个字节码?

22640 次浏览

根据编译器的不同,它应该映射到相同的字节代码。

从语义上讲,它们是完全等价的。这是一个味道的问题,但我认为 while(true)看起来更干净,更容易阅读和理解的第一眼。在 Java 中,它们都不会导致编译器警告。

在字节码级别,它可能取决于编译器和优化级别,但原则上发出的代码应该是相同的。

编辑:

在我的编译器中,使用 字节码大纲插件,for(;;){}的字节码如下所示:

   L0
LINENUMBER 6 L0
FRAME SAME
GOTO L0

while(true){}的字节码如下:

   L0
LINENUMBER 6 L0
FRAME SAME
GOTO L0

所以是的,至少对我来说,他们是一样的。

JVM 会找到制作字节码的最佳方法,而且在这两种情况下都应该这样做。而(真实的)只是更漂亮。

在功能上没有区别。与在循环体中运行的任何指令相比,字节码差异带来的任何效率都可能是微不足道的。

在 OracleJava7上,您会得到相同的字节码。你不能从字节代码中判断出在原始文件中使用了什么。哪一种最好是品味的问题。我用 while(true)

这取决于你使用哪一个,因为它们等于编译器。

创建文件:

// first test
public class Test {
public static void main(String[] args) {
while (true) {
System.out.println("Hi");
}
}
}

编译:

javac -g:none Test.java
rename Test.class Test1.class

创建文件:

// second test
public class Test {
public static void main(String[] args) {
for (;;) {
System.out.println("Hi");
}
}
}

编译:

javac -g:none Test.java
mv Test.class Test2.class

比较:

diff -s Test1.class Test2.class
Files Test1.class and Test2.class are identical

我查看了生成的字节代码,发现由于条件总是 没错(在编译时) ,编译器将编译掉测试,只是分支总是返回到循环的顶部。我假设 继续语句也会执行一个总是返回到循环顶部的分支。因此,它不仅没有任何区别,甚至没有任何代码生成来测试任何东西。

它可以编译成相同的字节码,这取决于您喜欢哪种结构。

我读了很多来自 Oracle 分布式 JDK 的源代码,我不太记得我在他们的代码中看到过 while(true)语句,但是我在他们的代码中看到过很多 for(;;)语句。就我个人而言,我喜欢 for(;;),我的理由有点像这样:

While-loop“ should”需要一个布尔表达式,而不是一个布尔常量。while(true)有点像 if(true),我认为它们都是合法的,只是为了增加大众的舒适度。不编译空 while()。在这里添加 true感觉有点像黑客。

另一方面,for(;;)是一个“真正的循环”,尽管是一个空的循环。而且,它还为您节省了几次按键!=)(这不重要)

因此,我知道这听起来很疯狂,但是尽管(true)在英语中读起来更好,我认为 for (; ;)更好地表达了您的意图,而且更类似于 Java 编程语言。无论如何都应该避免永恒的循环。当我阅读 for (;)时,我感到安全,因为知道开发人员将在某处制止执行路径。当我阅读 while (true)时,我就不能再那么肯定了。但是,也许只有我这么想!我们都可以自由选择自己喜欢的口味。

只是解析器所需的时间不同,两个不同的表达式包含不同数量的令牌,但计算时间差异非常小,编译后的字节码在两种情况下是相同的。