Почему не рекомендуется выбрасывать исключения типа RuntimeException без веской причины?

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

Ответ

RuntimeException и его подклассы — это unchecked исключения. Их не рекомендуется использовать для обработки ожидаемых ошибок бизнес-логики из-за особенностей дизайна Java.

Ключевые проблемы:

  1. Нарушение контракта метода: Компилятор не заставляет вызывающий код обрабатывать (try-catch) или объявлять (throws) RuntimeException. Это скрывает возможные ошибки, делая API менее понятным.
  2. Семантика ошибки: RuntimeException предназначен для обозначения ошибок программиста или непредвиденных сбоев среды выполнения (например, NullPointerException, ArrayIndexOutOfBoundsException). Использование его для валидации вводимых данных стирает эту границу.
  3. Сложность отладки: Так как обработка не обязательна, исключение может "всплыть" далеко от места возникновения, усложняя поиск корневой причины.

Пример: Валидация входного параметра

// ПЛОХО: Использование RuntimeException скрывает важную ошибку.
public void processOrder(int quantity) {
    if (quantity <= 0) {
        // Какой тип ошибки? Бизнес-логика или баг? Вызывающий код может не знать.
        throw new RuntimeException("Quantity must be positive");
    }
    // ... логика обработки
}

// ХОРОШО: Использование проверяемого (checked) исключения.
// Это явно указывает на возможный сбой в контракте метода.
public void processOrder(int quantity) throws InvalidOrderException {
    if (quantity <= 0) {
        throw new InvalidOrderException("Quantity must be positive");
    }
    // ... логика обработки
}

// Определение своего checked исключения:
class InvalidOrderException extends Exception {
    public InvalidOrderException(String message) {
        super(message);
    }
}

Когда использовать RuntimeException? Для ошибок, которые, по сути, являются багами и которые невозможно осмысленно обработать на более высоком уровне (например, неверная внутренняя реализация).