web-dev-qa-db-fra.com

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

Quelle est la différence entre une boucle while(true) standard et for(;;)?

Y en a-t-il, ou les deux seront-ils mappés sur le même bytecode après la compilation?

60
sjas

Sémantiquement, ils sont complètement équivalents. C'est une question de goût, mais je pense que while(true) semble plus propre, et est plus facile à lire et à comprendre à première vue. Dans Java aucun d'eux ne provoque d'avertissement du compilateur.

Au niveau du bytecode, cela peut dépendre du compilateur et du niveau d'optimisations, mais en principe le code émis doit être le même.

MODIFIER:

Sur mon compilateur, en utilisant le plugin Bytecode Outline , le bytecode pour for(;;){} ressemble à ceci:

   L0
    LINENUMBER 6 L0
   FRAME SAME
    GOTO L0

Et le bytecode pour while(true){} ressemble à ceci:

   L0
    LINENUMBER 6 L0
   FRAME SAME
    GOTO L0

Alors oui, du moins pour moi, ils sont identiques.

106
Óscar López

C'est à vous de décider lequel utiliser. Parce qu'ils sont égaux au compilateur.

créer un fichier:

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

compiler:

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

créer un fichier:

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

compiler:

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

comparer:

diff -s Test1.class Test2.class
Files Test1.class and Test2.class are identical
25
4ndrew

Il se compile dans le même code d'octet, et c'est une question de goût que vous construisez.

J'ai lu beaucoup de code source à partir du JDK distribué par Oracle, et je ne me souviens pas facilement que j'ai vu une instruction while(true) dans leur code, mais j'ai vu beaucoup de for(;;) instructions dans leur code. Personnellement, je privilégie for(;;) et mon raisonnement va un peu comme ceci:

La boucle while "devrait" nécessiter une expression booléenne, pas une constante booléenne. while(true) est un peu comme if(true), qui, je pense, n'a été rendu légal que pour le confort des masses. Une while() vide ne se compile pas. Ajouter le true là-dedans ressemble un peu au piratage.

for(;;) d'autre part est une "boucle réelle", bien que vide. De plus, cela vous évite quelques frappes! =) (peu importe)

Par conséquent, et je sais que cela semble fou, mais même si (true) lit mieux en anglais, je pense que (;;) exprime mieux votre intention et s'apparente davantage au langage de programmation Java Java. Les boucles éternelles devraient être évitées de toute façon. Lorsque je lis pour (;;), je me sens en sécurité en sachant que le développeur freinera le chemin d'exécution quelque part. juste moi! Nous sommes tous libres de choisir notre propre saveur.

7

Sur Oracle Java 7 vous obtenez le même code d'octet. Vous ne pouvez pas distinguer le code d'octet utilisé dans l'original. Le mieux est une question de goût. J'utilise while(true)

6
Peter Lawrey

JVM trouvera le meilleur moyen de créer du bytecode et dans les deux cas devrait faire de même, donc je pense qu'il n'y a pas de différence. tandis que (vrai) est juste plus joli.

3
shift66

J'ai regardé le code d'octet généré et j'ai constaté que puisque la condition est toujours true (au moment de la compilation), le compilateur compilera le test et se ramifiera toujours en haut de la boucle. Je suppose qu'une instruction continue fera également une branche toujours en haut de la boucle. Donc, non seulement cela ne fait aucune différence, il n'y a même pas de code généré pour tester quoi que ce soit.

3
Bruce Barton

Selon le compilateur, il doit correspondre au même code d'octet.

3
DMCS

Fonctionnellement, il n'y a pas de différence. Toute efficacité gagnée ou perdue par une différence de bytecode sera probablement insignifiante par rapport à toute instruction que vous exécuteriez dans le corps de la boucle.

2
Dev

Seule la différence est le temps requis pour l'analyseur, les deux expressions distinctes incluent un nombre différent de jetons à analyser, mais la différence de temps de calcul est très faible et le bytecode compilé est le même pour deux cas.

1
jbytecode