Ошибка компилятора кода недоступна

Следующий код дает ошибку unreachable statement компилятора

public static void main(String[] args) {
    return;
    System.out.println("unreachable");
}

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

public static void main(String[] args) {
    if (true) {
        return;
    }
    System.out.println("unreachable");
}

Мне просто интересно, почему это ошибка компилятора? Будет ли это нарушать Java-байт-код каким-то образом, защищать программиста или это что-то еще?

Также (и это для меня более интересно), если компиляция java в байт-код делает какую-либо оптимизацию (или даже если это не так), то почему он не обнаружит вопиющего недостижимого кода во втором примере? Что было бы псевдокодом компилятора для проверки того, что оператор недостижим?

Ответ 1

Недостижимый код не имеет смысла, поэтому ошибка времени компиляции полезна. Причина, по которой это не будет обнаружена во втором примере, как и вы ожидаете, предназначена для тестирования/отладки. Его объяснение в Спецификации:

if (false) { x=3; }

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

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

static final boolean DEBUG = false;

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

if (DEBUG) { x=3; }

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

Ссылка: http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.21

Ответ 2

Это потому, что автор компилятора предположил, что человек в элементах управления тупой и, вероятно, не хотел добавлять код, который никогда не будет выполняться, - поэтому, бросая ошибку, он пытается помешать вам непреднамеренно создать путь кода который не может быть выполнен - ​​вместо этого вы вынуждаете вас принять решение об этом (хотя, как вы доказали, вы все равно можете обойти его).

Ответ 3

Эта ошибка в основном предотвращает ошибки программиста (своп из двух строк и более). Во втором фрагменте вы даете понять, что вас не интересует system.out.println().

Ответ 4

Как-то он сломает байт-код Java, защищает ли он программиста или что-то еще?

Это не требуется для Java/JVM. Единственная цель этой ошибки компиляции - избегать глупых ошибок программиста. Рассмотрим следующий код JavaScript:

function f() {
    return 
        {
            answer: 42
        }
}

Эта функция возвращает undefined, поскольку механизм JavaScript добавляет точку с запятой в конец строки и игнорирует мертвый код (как он думает). Компилятор Java более умный, и когда он обнаруживает, что вы делаете что-то явно и явно неправильно, он не позволит вам сделать это. На земле у вас нет способа иметь мертвый код. Это как-то вписывается в предпосылку Java о том, чтобы быть безопасным языком.

Ответ 5

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

Во втором коде я поставил выше выражение return и его работу:)

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

public static void main (String [] args) {

return;
System.out.println("unreachable");

}

/////////////////////////////////

public static void main (String [] args) {

System.out.println("unreachable"); // Put the statement before return
return;

}

Ответ 7

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