Оптимизирует ли 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. Проверка исключений.

Другие вопросы по тегам