Как компилятор в Java выбирает недоступный код?

Как компилятор выбирает недоступный код?

рассмотреть эти

public class Test15 {

    public static final boolean verdict = false;
    public static final int verdictInt = 2;

    public static void main(String[] args) throws IOException {

        // case1
        if (verdict) {
            System.out.println(1);
        } else {
            System.out.println(2);
        }// compiles

        //case 2
        int val = 5;
        switch (val) {
         case verdictInt:System.out.println(3);
                        break;
        }// compiles

        //case 3
        while (false) {

        }// does not compile

        //case 4
        return 6;
        return 7;
        //does not compile

    }
}

Поэтому, когда компилятор решает, что код недоступен. Это из-за (из-за отсутствия лучшего термина) жесткого кода (как в случае 4). Поскольку, по моим сведениям, вердикт, verdictInt также квалифицируется как константы времени компиляции и соответственно. И, согласно моему прочтению, возможность использовать константу verdictInt в качестве метки регистра переключателя указывает, что это константа времени компиляции.

Пожалуйста, дайте мне знать, если в моих рассуждениях есть какие-то основные недостатки.

2 ответа

Решение

Раздел Спецификации языка Java о недоступном коде хорош, но долго читается. Я сведу это к тому, что переводит на ваш вопрос.

Случай 1:

verdict может рассматриваться как переменная флага; это может или не может использоваться для целей отладки. Если это так, то нарушение компиляции может привести к главной цели проекта. Спецификация явно вызывает это:

Обоснование для этого различного лечения [с if в отличие от while ] позволяет программистам определять "переменные-флажки", такие как:

static final boolean DEBUG = false;

а затем написать код, такой как:

if (DEBUG) { x=3; }

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

Случай 2:

Ваш switch Оператор может нормально завершиться по правилам JLS:

switch оператор может завершиться нормально, если хотя бы одно из следующих условий верно:

  • switch Блок пуст или содержит только метки переключателей.
  • Последнее утверждение в switch блок может завершиться нормально.
  • Есть хотя бы один switch ярлык после последнего switch блок операторов группы.
  • switch блок не содержит default этикетка.
  • Есть достижимый break заявление, которое выходит из switch заявление.

Ваш switch не имеет default ярлык, чтобы ваш переключатель мог завершиться нормально. Это просто выпадает из выключателя.

Случай 3:

Это явно не компилируется. Случай 1 привлек к нему некоторое внимание, но здесь это прописано, выделение мое:

while оператор может завершиться нормально, если хотя бы одно из следующих условий верно:

  • while оператор достижим, и выражение условия не является константным выражением (§15.28) со значением true,

  • Есть достижимый break заявление, которое выходит из while заявление.

Содержимое утверждение достижимо, если while оператор достижим, и выражение условия не является константным выражением, значение которого равно false ,

Выражение условия false, так что вы не можете получить доступ к содержащемуся утверждению по определению.

Дело 4:

return это особый случай; это завершается внезапно. Как только оператор завершается преждевременно, любые операторы после него не достижимы по определению.

В случае 3 он знает, что это не цикл, потому что значение всегда ложно. В случае 4 он знает, что раньше был бесконечный цикл, поэтому он говорит о недоступном коде. Но верните 7; недоступен также из-за возврата 6; перед этим всегда бегаю.

Это как делать:

printf("Hello");
return 0;
printf("Never reached code");

Я не знаю, приведет ли это к недостижимой ошибке:

final int i = 5; float x = 0;
while(i<8) {
    x += 0.001f; 
    // Do Nothing
}
printf("Hello World");
Другие вопросы по тегам