Получить доступ

Исключения: иерархия и checked/unchecked

Дерево Throwable, философия checked против unchecked, раскрутка стека и стоимость, цепочки причин и практики обработки.

Иерархия Throwable

Корень — Throwable (только его объект можно бросить и поймать). От него две ветви: Error и Exception. Error — серьёзные сбои окружения, из которых обычно не восстанавливаются и которые не ловят: OutOfMemoryError, StackOverflowError, NoClassDefFoundError.

Exception — прикладные ситуации, которые код может обработать. Внутри неё особняком стоит RuntimeException — ветка unchecked, куда попадают ошибки программиста: NullPointerException, IllegalArgumentException, IllegalStateException, ClassCastException.

Checked против unchecked

Checked-исключения (наследники Exception, кроме RuntimeException) проверяются компилятором: их нужно либо объявить в throws, либо обработать. Unchecked (RuntimeException и Error) компилятор обрабатывать не требует.

Философия: checked — для ожидаемых восстановимых ситуаций, на которые вызывающий реально может среагировать (нет файла, сетевой сбой); unchecked — для багов и нарушений контракта, которые надо чинить в коде, а не «обрабатывать».

Важный нюанс зрелости: checked-исключения критикуют за многословие и за то, что они плохо дружат с лямбдами и Stream API — функциональные интерфейсы (Function, Supplier) не объявляют throws, поэтому checked из лямбды не бросить без обёртки. Поэтому многие современные библиотеки и фреймворки тяготеют к unchecked.

Что происходит при выбросе

Когда исключение брошено, JVM раскручивает стек (stack unwinding): идёт вверх по кадрам методов в поисках ближайшего подходящего catch, по пути выполняя блоки finally. Если обработчик не найден до вершины стека потока — поток завершается, и печатается stack trace.

Это объясняет, почему исключения не стоит использовать для нормального потока управления: основная стоимость — заполнение stack trace (fillInStackTrace обходит весь стек) при создании исключения. Само бросание/ловля дёшевы, дорого именно построение трассы.

Цепочки причин и не-глотание

При перехвате на границе слоёв исключение оборачивают, сохраняя первопричину: throw new ServiceException("...", e). Тогда getCause() и печать трассы покажут всю цепочку «Caused by: …» — это бесценно при отладке. Терять cause (бросать new без e) — распространённая ошибка.

Антипаттерны обработки: пустой catch (глотание ошибки), слишком широкий catch (Exception) или catch (Throwable) (ловит и баги, и Error), а также «залогировал и пробросил» (двойные логи одной ошибки на разных слоях). Несколько типов ловят одним multi-catch: catch (IOException | SQLException e).

try {
    repository.save(order);
} catch (SQLException e) {
    throw new OrderPersistenceException("не удалось сохранить заказ", e); // сохраняем cause
}

Практики и fail-fast

Бросайте максимально конкретное исключение и проверяйте предусловия рано (fail-fast): неверный аргумент — IllegalArgumentException, недопустимое состояние объекта — IllegalStateException, null-аргумент — Objects.requireNonNull(x, "x") (бросит NPE с понятным сообщением сразу, а не где-то глубже).

Кастомные исключения заводят, когда вызывающему нужно различать ситуацию программно; в них кладут осмысленные поля (id сущности, код ошибки), а не только текст. И помните смежное правило из многопоточности: поймав InterruptedException, восстановите флаг прерывания, а не глотайте его.

Как отвечать на собеседовании

Нарисуйте дерево Throwable (Error не ловим; Exception/RuntimeException), объясните философию checked/unchecked и их трение с лямбдами, опишите раскрутку стека и что дорого именно построение stack trace (значит, не для control flow). Подчеркните сохранение cause при оборачивании и fail-fast (requireNonNull, IllegalArgument/StateException), назовите антипаттерны (пустой/широкий catch, log-and-rethrow).

Вопросы по теме

Читайте также

Закрытая бета

Знать тему — половина дела

На живом собеседовании sotto слышит вопрос интервьюера и показывает короткий ответ и план. Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем