Error-ов бояться – на джаве не писать! Наверное, ты уже кое-что знаешь об исключениях в Java. Сегодня хотя бы поверхностное знание тебе пригодится: мы будем разбирать класс Error и особый тип исключений, который многих “пугает”, появляясь в их Стектрейсах.

Во главе иерархии исключений в Java стоит класс Throwable, у которого есть два наследника:

  • Exception, который отвечает за ошибки в системе.
  • И наш сегодняшний герой — Error, который отвечает за ошибки JVM.
    Стоит сказать, что это скорее даже не ошибки, а проблемы, которые обычно не зависят от разработчика.

Что делать с Error

Отлавливая “эрроры”, выполнить какие-либо действия в блоке catch, кроме логирования, тебе не удастся, так как это проблемы самой JVM.

Логирование — хорошее дело: получив ошибку во время выполнения программы, ты можешь посмотреть в логи, увидеть причину поломки и знать, что исправлять.

Так как ты не знаешь, какой error можешь получить, создавая свой код, вписывать в блок catch какой-то конкретный тип нет смысла. Использовать сам класс Error — тоже не самое удачное решение: в таком случае будешь ловить только ошибки.

Поэтому лучше использовать класс Throwable, который может поймать и исключения типа Error, и Exception. Как это выглядит на практике?

Так писать не ОК:

try {
    //Твой код
} catch (OutOfMemoryError outOfMemoryError) {
    //Код для отловки OutOfMemoryError
}
Так писать —тоже не ОК:

try {
    //Твой код
} catch (Error error) {
    //Код для отлова всех Error
}
А вот так писать — ОК:

try {
    //Твой код
} catch (Throwable throwable) {
    //Код для отлова всех Throwable
}

Второй вариант обработки error-ов — это пробрасывание их дальше с помощью ключевого слова throws на уровне метода. Такой способ используют в случаях, когда твой код теоретически может бросить ошибку типа error, и ты хочешь сообщить это всем, кто будет использовать твой код, чтобы они могли его обработать.

Распространенные error-ы

Одни из самых популярных эрроров — классы OutOfMemoryError и StackOverflowError.

OutOfMemoryError часто появляется в тех случаях, когда программе не хватает места для создания объектов, сборщик мусора обработать не успевает, и как результат – OutOfMemoryError.

В Java ты не можешь контролировать удаление объектов, чтобы предотвратить утечки памяти, но ты можешь не мусорить, чтобы не давать лишней работы Garbage Collector-у и не засорять heap (кучу).

Например, такого типа код будет порождать много мусора в памяти:


while (true) {
    new Object();
}

Вторая ошибка, о которой хочу тебе рассказать, — это StackOverflowError: выбрасывается в случаях, когда переполняется стек. Так как стек в основном хранит локальные переменные, параметры и вызовы методов, очень частой причиной этого является рекурсия, или рекурсивный вызов метода:


public void foo() {
    foo();
}

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

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

Разница между исключениями типа Error и Exception

Error Exception
Нельзя исправить в блоке catch Можно обработать в блоке catch
Не появится во время компиляции Можно словить на этапе компиляции
Проблемы JVM Проблемы логики кода
Все Error unchecked checked и unchecked

Без исключений в Java никак, но бояться их не стоит. Просто нужно понимать, что обозначает каждый из типов, и знать, как их обрабатывать. На сегодня это все. Увидимся!