Бесконечные циклы в Java - PullRequest
       72

Бесконечные циклы в Java

82 голосов
/ 20 декабря 2011

Посмотрите на следующий бесконечный цикл while в Java.Это приводит к ошибке времени компиляции для оператора ниже.

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

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

Следующий тот же бесконечный цикл while, однако работает нормально и не выдает никаких ошибок, в которых я только что заменилусловие с логической переменной.

boolean b=true;

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

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

Кроме того, во втором случае оператор после цикла явно недостижим, потому что логическая переменная b верна, но компилятор вообще не жалуется,Почему?


Редактировать: Следующая версия while застревает в бесконечном цикле как очевидный, но не выдает ошибок компилятора для оператора ниже, даже если ifусловие в цикле всегда равно false, и, следовательно, цикл никогда не может вернуться и может быть определен компилятором во время самой компиляции.

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.

Редактировать: То же самое с if и 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.
}      

Следующееверсия while также застревает в бесконечном цикле.

while(true) {

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

Это потому, что блок finally всегда выполняется, даже если оператор return встречается до него внутри самого блока try.

Ответы [ 15 ]

3 голосов
/ 20 декабря 2011

Компилятор не достаточно сложен, чтобы пройти через значения, которые может содержать b (хотя вы назначаете его только один раз). В первом примере компилятору легко увидеть, что это будет бесконечный цикл, поскольку условие не является переменным.

2 голосов
/ 21 декабря 2011

Первое выражение всегда приводит к бесконечному циклу, потому что мы должны указать константу в условии цикла while, где, как и во втором случае, компилятор предполагает, что существует возможность изменения значения b внутри цикла.

2 голосов
/ 20 декабря 2011

Выражения вычисляются во время выполнения, поэтому, заменяя скалярное значение «true» чем-то вроде логической переменной, вы заменяете скалярное значение на логическое выражение, и, таким образом, компилятор не может узнать его во время компиляции.

2 голосов
/ 20 декабря 2011

Если компилятор может окончательно определить, что логическое значение будет оцениваться до true во время выполнения, он выдаст эту ошибку. Компилятор предполагает, что переменная, которую вы объявили , может быть изменена (хотя мы знаем здесь, как люди, что это не так).

Чтобы подчеркнуть этот факт, если переменные объявлены как final в Java, большинство компиляторов выдаст ту же ошибку, как если бы вы заменили значение. Это связано с тем, что переменная определяется во время компиляции (и не может быть изменена во время выполнения), и поэтому компилятор может окончательно определить, что выражение оценивается как true во время выполнения.

2 голосов
/ 20 декабря 2011

С точки зрения компилятора b в while(b) может где-то измениться на false.Компилятор просто не проверяет.

Для развлечения попробуйте while(1 < 2), for(int i = 0; i < 1; i--) и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...