82 votes

Boucles infinies en Java

Regardez les suivantes infinie while boucle en Java. Il provoque une erreur de compilation pour la déclaration ci-dessous.

while(true) {
    System.out.println("inside while");
}

System.out.println("while terminated"); //Unreachable statement - compiler-error.

Le suivant du même infinie while boucle, cependant, fonctionne très bien et n'émet pas de toutes les erreurs dont je viens de remplacer la condition d'une variable booléenne.

boolean b=true;

while(b) {
    System.out.println("inside while");
}

System.out.println("while terminated"); //No error here.

Dans le second cas, également, de l'instruction après la boucle est évidemment inaccessible car la variable booléenne b est vrai encore que le compilateur ne se plaint pas du tout. Pourquoi?


Edit : La prochaine version de l' while rester coincé dans une boucle infinie comme évident, mais les enjeux n'erreurs du compilateur pour la déclaration ci-dessous, même si l' if condition dans la boucle est toujours false et, par conséquent, la boucle peut ne jamais revenir et peut être déterminée par le compilateur au moment de la compilation elle-même.

while(true) {

    if(false) {
        break;
    }

    System.out.println("inside while");
}

System.out.println("while terminated"); //No error here.

while(true) {

    if(false)  { //if true then also
        return;  //Replacing return with break fixes the following error.
    }

    System.out.println("inside while");
}

System.out.println("while terminated"); //Compiler-error - unreachable statement.

while(true) {

    if(true) {
        System.out.println("inside if");
        return;
    }

    System.out.println("inside while"); //No error here.
}

System.out.println("while terminated"); //Compiler-error - unreachable statement.

Edit : Même chose avec if et while.

if(false) {
    System.out.println("inside if"); //No error here.
}

while(false) {
    System.out.println("inside while");
    // Compiler's complain - unreachable statement.
}

while(true) {

    if(true) {
        System.out.println("inside if");
        break;
    }

    System.out.println("inside while"); //No error here.
}      

La prochaine version de l' while également rester coincé dans une boucle infinie.

while(true) {

    try {
        System.out.println("inside while");
        return;   //Replacing return with break makes no difference here.
    } finally {
        continue;
    }
}

C'est parce que l' finally bloc est toujours exécutée même si l' return instruction rencontre dans l' try bloc lui-même.

105voto

lwburk Points 29313

Le compilateur peut facilement et sans équivoque prouver que la première expression toujours des résultats dans une boucle infinie, mais il n'est pas facile pour le deuxième. Dans votre jouet exemple, il est simple, mais que faire si:

  • la variable contenu a été lu à partir d'un fichier?
  • la variable n'est pas local et peut être modifié par un autre thread?
  • la variable compté sur quelque la saisie de l'utilisateur?

Le compilateur n'est clairement pas la vérification de votre cas plus simple parce que c'est de renoncer à la route tout à fait. Pourquoi? Parce que c'est beaucoup plus difficile interdite par la spécification. Voir la section 14.21:

(En passant, mon compilateur ne se plaignent lorsque la variable est déclarée final.)

55voto

Kibbee Points 36474

Selon les spécifications, le suivant est dit à propos de tout consolidés.

Une instruction while peut se terminer normalement le forum au moins une des suivantes est remplie:

  • L'instruction while est accessible et l'expression de condition n'est pas une expression constante avec la valeur true.
  • Il est accessible instruction break qui sort de l'instruction while.\

Ainsi, le compilateur va seulement dire que le code à la suite d'une instruction while est inaccessible si la condition du while est une constante avec une valeur true, ou il y a une instruction de saut dans le temps. Dans le second cas, puisque la valeur de b n'est pas une constante, elle ne considère pas le code qui suit pour être inaccessible. Il y a beaucoup plus d'informations derrière ce lien pour vous donner plus de détails sur ce qui est et ce qui n'est pas considéré comme inaccessible.

14voto

hope_is_grim Points 1589

Parce que le vrai est constante et b peut être changé dans la boucle.

10voto

kba Points 10874

Parce que l'analyse de la variable d'état est dur, de sorte que le compilateur a à peu près juste donné vers le haut et laissez-vous faire ce que vous voulez. En outre, le Langage Java Specification a des règles claires sur la manière dont le compilateur est permis de détecter du code inaccessible.

Il existe de nombreuses façons de tromper le compilateur - un autre exemple courant est

public void test()
{
    return;
    System.out.println("Hello");
}

ce qui ne va pas, comme le compilateur se rendrait compte que la zone a été unreacable. Au lieu de cela, vous pourriez faire

public void test()
{
    if (2 > 1) return;
    System.out.println("Hello");
}

Ce serait le travail depuis le compilateur n'est pas en mesure de réaliser que l'expression ne sera jamais faux.

6voto

Cheesegraterr Points 189

Ce dernier n’est pas inaccessible. Le booléen b a encore la possibilité d’altération false quelque part à l’intérieur de la boucle provoquant une condition de finale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X