Как компилятор в 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");