Подтвердить что ты не робот

(Компилятор) else if (true) vs else

Возьмите следующий фрагмент кода Java:

....
    else if (true){ //hard-coded as true
     ///launch methodA
    }
    else {
     ///launch methodA (same code as in the ` else if ` statement)
    }
....

Мне было интересно, как с этим справляется компилятор. Было бы логичным, если бы компилятор вообще не удалял оператор else if(true), чтобы не выполнять проверку, даже если он жестко закодирован как истинный. В частности, в Eclipse, как интерпретируется код выше?

Или как в следующем сценарии:

....
    else if (true){ //hard-coded as true
     ///launch methodA
    }
    else {
     ///launch methodBB
    }
....

Не было бы логичным в этом случае для компилятора удалить инструкцию else? Потому что во время работы оператор else недоступен.

4b9b3361

Ответ 1

Недопустимые утверждения запрещены в Java и должны приводить к ошибкам компиляции. JLS определяет, что является недостижимым: https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21

Слишком много времени для полного цитирования здесь, но вот выдержка (emphasis):

if (false) { x=3; }

не приводит к ошибке времени компиляции. Оптимизирующий компилятор можетчто утверждение x = 3; никогда не будет выполняться и может выбрать опустить код для этого оператора из сгенерированного файла класса, но утверждение x = 3; не рассматривается как "недостижимый" в технических смысл, указанный здесь.

Обоснование этого различного обращения заключается в том, чтобы позволить программистам определить "переменные флага", такие как:

static final boolean DEBUG = false;

а затем напишите код, например:

if (DEBUG) { x=3; }

Идея состоит в том, что должно быть возможно изменить значение DEBUG с false на true или с true на false, а затем скомпилировать код правильно, без каких-либо изменений текста программы.

Таким образом, ответ будет зависеть от используемого вами компилятора и его параметров оптимизации.

Ответ 2

Компилятор выбирает его во время компиляции:

public class Test {
    public static void main(String[] args) {
    if(true) {
        System.out.println("Hello");
    } else {
        System.out.println("Boom");
    }
}

Дает мне (с моим Java 1.8.0_45):

Compiled from "Test.java"
public class Test {
  publicTest();
    Code:
       0: aload_0
       1: invokespecial #1        // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2        // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3        // String Hello
       5: invokevirtual #4        // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

Код просто печатает Hello. Boom даже не рассматривается.

Все последние компиляторы Java исключают мертвый код во время компиляции.

Ответ 3

Нет конкретного ответа на этот вопрос. Это зависит от компилятора Java. Большинство компиляторов игнорируют Dead Code, потому что это не изменит семантику кода, даже если это приведет к созданию более крупного файла класса.

Если вас интересует такой анализ, существует много литературы о ликвидации Dead Code.

Ответ 4

Вы можете попробовать написать код и декомпилировать файл класса. Мой компилятор оптимизирует

else if (true){ //hard-coded as true
 ///launch methodA
}
else {
 ///launch methodA (same code as in the else if statement)
}

а

else {
 ///launch methodA
}

и

else if (true){ //hard-coded as true
 ///launch methodA
}
else {
 ///launch methodBB
}

а

else {
 ///launch methodA
}

Я думаю, что все версии компилятора будут оптимизировать его таким образом.

Ответ 5

В частности, о Eclipse, он собирается предупредить вас, что последний блок еще недоступен, но компиляция делегирована вашему jdk, поэтому, возможно, именно компилятор предупреждает Eclipse.

Ответ 6

теперь я пишу код в eclipse мой метод

     public static void aa(String b){
        if (true) {

        }

        else if (true) {
            System.out.println("asas");
        } else {

        }
       }

После того, как я скомпилировал свой код и декомпилятор мой код с JD-GUI.My код декомпилятора:

  public static void aa(String b) {}

}

результат очень хороший:)

Ответ 7

Не было бы логичным, если бы компилятор вообще удалял оператор else if (true), чтобы не выполнять проверку, даже если он жестко закодирован как истинный.

Нет, не было бы, если бы оба блока не имели одинаковый контент и почему бы это проверить? Это было бы семантически неправильно. Что было бы логичным для компилятора, чтобы удалить окончательный недостижимый else, и это то, что он делает.

Ответ 8

Похожие ответы: Java If (false) Compile

Обратите особое внимание на использование javap -c для диагностики байт-кода, чтобы определить, действительно ли был удален мертвый код. fooobar.com/info/251739/...