web-dev-qa-db-ja.com

Java:for(;;)vs. while(true)

標準のwhile(true)ループとfor(;;)の違いは何ですか?

コンパイル後に同じバイトコードにマッピングされますか、または両方がマッピングされますか?

60
sjas

意味的には、それらは完全に同等です。それは好みの問題ですが、while(true)はよりきれいに見え、一見すると読みやすく、理解しやすいと思います。 In Javaどちらもコンパイラ警告を引き起こしません。

バイトコードレベルでは、コンパイラと最適化のレベルに依存する可能性がありますが、原則として、出力されるコードは同じである必要があります。

編集:

私のコンパイラでは、 Bytecode Outline プラグインを使用して、for(;;){}のバイトコードは次のようになります。

_   L0
    LINENUMBER 6 L0
   FRAME SAME
    GOTO L0
_

while(true){}のバイトコードは次のようになります。

_   L0
    LINENUMBER 6 L0
   FRAME SAME
    GOTO L0
_

はい、少なくとも私にとっては、それらは同一です。

106
Óscar López

どちらを使用するかはあなた次第です。原因はコンパイラに等しいからです。

ファイルを作成:

// 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
25
4ndrew

同じバイトコードにコンパイルされ、好みの構成が好みです。

Oracleの分散JDKから多くのソースコードを読みましたが、コードにwhile(true)ステートメントがあったことを簡単に思い出せませんが、for(;;)ステートメントはたくさん見ました。そのコードで。私個人としては、for(;;)を好みます。私の推論は次のようになります。

While-loopには、ブール定数ではなくブール式が必要です。 while(true)if(true)に少し似ていますが、どちらも大衆の快適さのためにのみ合法化されたと思います。空のwhile()はコンパイルされません。そこにtrueを追加すると、ハッキングのように感じます。

一方、for(;;)は空のループですが、「実際のループ」です。また、キーストロークを数回節約できます! =)(重要ではない

したがって、私はそれが狂ったように聞こえることを知っていますが、英語では(true)の方が読みやすいですが、for(;;)はあなたの意図をよりよく表現し、Javaプログラミング言語に似ています)とにかく永遠のループを避ける必要があります。for(;;)を読むとき、開発者がどこかで実行パスを壊すことを知っていると安心します。while(true)を読むとき、私はもう確信できません。私だけ!私達は私達の味を選ぶことはすべて自由です。

7

Oracleでは、Java 7で同じバイトコードを取得します。オリジナルで使用していたバイトコードからは判断できません。最適なのは好みです。while(true)

6
Peter Lawrey

JVMはバイトコードを作成するための最良の方法を見つけますが、どちらの場合も同じことを行う必要があります。したがって、違いはないと思います。 while(true)は単にきれいです。

3
shift66

生成されたバイトコードを確認しましたが、条件は常にtrue(コンパイル時)であるため、コンパイラーはテストをコンパイルし、常にループの先頭に分岐します。 continueステートメントは、常にループの先頭に戻る分岐も行うと想定しています。そのため、違いを生まないだけでなく、何かをテストするために生成されたコードすらありません。

3
Bruce Barton

コンパイラによっては、同じバイトコードにマップする必要があります。

3
DMCS

機能的には違いはありません。バイトコードの違いによって得られる、または失われる効率は、ループの本体で実行する命令と比較して、おそらく重要ではありません。

2
Dev

パーサーに必要な時間は違いだけです。2つの異なる式には異なる数のトークンが解析されますが、計算時間の差は非常に小さく、コンパイルされたバイトコードは2つのケースで同じです。

1
jbytecode