Можно ли в Java перехватить исключение типа Error с помощью блока catch?

«Можно ли в Java перехватить исключение типа Error с помощью блока catch?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Технически — да, можно, но делать этого почти никогда не следует.

Error и его подклассы (например, OutOfMemoryError, StackOverflowError, VirtualMachineError) представляют собой критические системные ошибки, из которых приложение обычно не может или не должно корректно восстанавливаться.

Почему это плохая практика?

  1. Маскировка фатальных проблем: Перехват Error может скрыть серьезные сбои JVM (нехватка памяти, ошибки загрузки классов), что приведет к нестабильному и непредсказуемому состоянию приложения.
  2. Невозможность гарантированного восстановления: После OutOfMemoryError состояние JVM может быть повреждено, и дальнейшая работа ненадежна.
  3. Нарушение контракта: Error предназначен для обработки JVM, а не логики приложения.

Допустимые исключения (очень редкие случаи):

try {
    // Код, который может выбросить что-то нестандартное
} catch (AssertionError e) {
    // Может быть уместно, если AssertionError используется в специфической логике тестирования
    log.warn("Assertion failed", e);
} catch (Throwable t) {
    // Крайний случай, например, в framework-коде или корневом обработчике потока
    // для логирования перед аварийным завершением
    log.fatal("Fatal JVM error", t);
    System.exit(1);
}

Вывод: Не ловите Error в бизнес-логике. Если возникает необходимость (например, в библиотеках или контейнерах), делайте это на самом верхнем уровне, только для логирования и безопасного завершения работы.