Оптимизирует ли java-компилятор ветки перехвата недостижимых исключений? - PullRequest
0 голосов
/ 07 февраля 2019

Почему код

void methodThrowsException() /*throws  Exception*/{
    try {
      // throw new Exception();
    } catch (Exception e) {
      throw e;
    }
}

хорошо скомпилирован?Компилятор AFAIK не анализирует код, может ли он генерировать исключение или нет.Здесь очевидное throw e; никогда не запустится (из-за комментариев // throw new Exception();), но почему компилятор знает это?

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Компилятор обнаружит определенное проверенное исключение, которое не было сгенерировано, например,

void methodThrowsException() {
    try {
    } catch (URISyntaxException e) {
        throw e;
    }
}

приведет к ошибке компилятора:

exception java.net.URISyntaxException is never thrown in body of corresponding try statement

, но он не будет проверять исключения во время выполнения илитипы корней иерархии исключений, такие как Exception, Error, Throwable.Это объясняется в JLS 11.2.3.Проверка исключений .

0 голосов
/ 07 февраля 2019

Javac-компилятор действительно мало оптимизирует.Но простое обнаружение и оптимизация мертвого кода пока возможны.

В вашем примере: компилятор может легко обнаружить, что блок try пуст.Пустые блоки try не могут сгенерировать, поэтому весь код блока catch по существу dead .

Таким образом, компилятор может войти и просто отбросить всю попытку / поймать здесь.Тогда не осталось ничего, что могло бы вызвать исключение.

Что, когда мы используем javap, это именно то, что мы находим в байт-коде:

  void methodThrowsException();
    Code:
       0: return

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

...