Оптимизирует ли java-компилятор ветки перехвата недостижимых исключений?
Почему код
void methodThrowsException() /*throws Exception*/{
try {
// throw new Exception();
} catch (Exception e) {
throw e;
}
}
хорошо скомпилировано? Компилятор AFAIK не анализирует код, может ли он генерировать исключение или нет. Здесь очевидно throw e;
никогда не будет работать (из-за комментариев // throw new Exception();
), но почему компилятор знает это?
2 ответа
Javac-компилятор действительно мало оптимизирует. Но простое обнаружение и оптимизация мертвого кода все же возможны.
В вашем примере: компилятор может легко обнаружить, что блок try пуст. Пустые блоки try не могут выбрасывать, поэтому весь код блока catch по сути мертв.
Таким образом, компилятор может войти и просто отбросить всю попытку / поймать здесь. Тогда не осталось ничего, что могло бы вызвать исключение.
Что, когда мы используем javap, это именно то, что мы находим в байт-коде:
void methodThrowsException();
Code:
0: return
И да, другой ответ является полностью правильным: это работает только потому, что вы используете Exception
более конкретный (проверенный) подкласс приведет к ошибке компилятора.
Компилятор обнаружит определенное проверенное исключение, которое не выдается, например
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. Проверка исключений.