Можно ли и нужно ли ловить Error в Java?

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

Ответ

Технически — да, можно. Error является подклассом Throwable, поэтому его можно перехватить блоком catch. Но делать это почти всегда — плохая практика.

В чём разница между Error и Exception?

  • Exception (например, IOException, SQLException): проблемы, от которых программа может разумно попытаться восстановиться.
  • Error (например, OutOfMemoryError, StackOverflowError, VirtualMachineError): указывает на серьёзные, фатальные проблемы в среде выполнения JVM (нехватка памяти, краш JVM), которые приложение обычно не может и не должно обрабатывать.

Пример перехвата (который лучше не использовать):

try {
    // Код, который может исчерпать память
    byte[] hugeArray = new byte[Integer.MAX_VALUE];
} catch (OutOfMemoryError e) {
    // Поймали Error, но что дальше?
    System.err.println("Не хватает памяти: " + e.getMessage());
    // Приложение, скорее всего, в нестабильном состоянии.
}

Правильные подходы:

  1. Не ловите Error. В большинстве случаев правильное действие — дать приложению завершиться, чтобы системные администраторы или мониторинг узнали о проблеме.
  2. Исключение для специфичных сценариев: Очень редко перехват Error может быть оправдан, например, в рамках:
    • Логирования для сбора диагностической информации перед завершением.
    • Очистки ресурсов (хотя try-with-resources и финализаторы тоже сработают).
    • Обработки AssertionError в тестовых фреймворках.

Главное правило: Не пытайтесь «продолжить работу как ни в чём не бывало» после Error. Состояние JVM ненадёжно.