← Назад к вопросам

Когда используются Runtime исключения?

2.0 Middle🔥 201 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Когда использовать Runtime исключения

Runtime исключения (unchecked exceptions) — это исключения, которые наследуются от RuntimeException. Они не требуют явной обработки в коде (try-catch или throws), но это не значит, что их игнорировать нужно.

Иерархия исключений в Java

Все исключения наследуют от Throwable:

Throwable
  ├── Exception
  │   ├── IOException (checked)
  │   ├── SQLException (checked)
  │   └── RuntimeException (unchecked)
  │       ├── NullPointerException
  │       ├── IndexOutOfBoundsException
  │       ├── IllegalArgumentException
  │       └── ArithmeticException
  └── Error
      ├── OutOfMemoryError
      ├── StackOverflowError
      └── NoClassDefFoundError

Когда использовать Runtime исключения

Runtime исключения используются для ошибок программиста (bugs):

1. NullPointerException

Возникает при попытке обращения к методу/полю null объекта:

String str = null;
int length = str.length();  // NullPointerException

Используется когда:

  • Нужно обозначить, что переменная не должна быть null
  • Это ошибка логики программы
  • Для проверки требований к аргументам:
public void processUser(User user) {
    if (user == null) {
        throw new NullPointerException("User cannot be null");
    }
    // Обработка
}

// Лучше с Java 14+ Objects:
import java.util.Objects;

public void processUser(User user) {
    Objects.requireNonNull(user, "User cannot be null");
    // Обработка
}

2. IllegalArgumentException

Для невалидных аргументов метода:

public void setAge(int age) {
    if (age < 0 || age > 150) {
        throw new IllegalArgumentException("Age must be between 0 and 150, got: " + age);
    }
    this.age = age;
}

// Пример использования
try {
    user.setAge(-5);  // Выбросит исключение
} catch (IllegalArgumentException e) {
    System.err.println("Invalid age: " + e.getMessage());
}

3. IndexOutOfBoundsException

При обращении к элементу вне границ коллекции/массива:

List<String> list = Arrays.asList("a", "b", "c");
String item = list.get(10);  // IndexOutOfBoundsException

Правильная обработка:

public String getItem(List<String> list, int index) {
    if (index < 0 || index >= list.size()) {
        throw new IndexOutOfBoundsException(
            "Index " + index + " out of range [0, " + list.size() + ")"
        );
    }
    return list.get(index);
}

4. ClassCastException

При неправильном приведении типов:

Object obj = "string";
Integer num = (Integer) obj;  // ClassCastException

Правильный способ:

public <T> T safeCast(Object obj, Class<T> type) {
    if (!type.isInstance(obj)) {
        throw new ClassCastException(
            "Cannot cast " + obj.getClass().getName() + " to " + type.getName()
        );
    }
    return type.cast(obj);
}

5. IllegalStateException

Когда объект находится в некорректном состоянии:

public class DatabaseConnection {
    private boolean isConnected = false;
    
    public void executeQuery(String sql) {
        if (!isConnected) {
            throw new IllegalStateException("Connection is not established");
        }
        // Выполнение запроса
    }
    
    public void connect() {
        this.isConnected = true;
    }
}

6. UnsupportedOperationException

Для неподдерживаемых операций:

public class ImmutableList<T> implements List<T> {
    @Override
    public void add(T element) {
        throw new UnsupportedOperationException("This list is immutable");
    }
    
    @Override
    public void remove(int index) {
        throw new UnsupportedOperationException("This list is immutable");
    }
}

Checked vs Unchecked исключения

Checked исключения (IOException, SQLException):

public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path);  // Требует обработки
    // ...
    reader.close();
}

ДОЛЖНЫ быть обработаны или пробросены.

Unchecked исключения (Runtime):

public void processData(String data) {
    if (data == null) {
        throw new NullPointerException("Data cannot be null");
    }
    // Обработка данных
}

Не требуют явной обработки (хотя это может быть сделано).

Создание своих Runtime исключений

public class ValidationException extends RuntimeException {
    public ValidationException(String message) {
        super(message);
    }
    
    public ValidationException(String message, Throwable cause) {
        super(message, cause);
    }
}

// Использование
public void validateEmail(String email) {
    if (!email.contains("@")) {
        throw new ValidationException("Invalid email format: " + email);
    }
}

Best Practices

✅ Используй Runtime исключения для:

  • Ошибок программиста, которые не должны происходить
  • Валидации входных данных
  • Проверки предусловий (preconditions)
  • Проверки инвариантов объекта

❌ НЕ используй Runtime исключения для:

  • Обработки ожидаемых сбоев (I/O, network, database) → Checked exceptions
  • Управления потоком выполнения (не используй как continue/break)
  • Условного контроля (используй if/else вместо try-catch)

Антипаттерны

// ПЛОХО — исключение для control flow
try {
    for (int i = 0; ; i++) {
        list.get(i);  // IndexOutOfBoundsException как сигнал конца
    }
} catch (IndexOutOfBoundsException e) {
    // Конец списка
}

// ХОРОШО
for (int i = 0; i < list.size(); i++) {
    // Обработка
}

Итоговая рекомендация

Runtime исключения — это способ сигнализировать о нарушении контракта между кодом и его клиентом. Они означают, что вызывающий код нарушил требования (передал null, невалидное значение, вызвал метод в неправильном состоянии). Это ошибки программиста, которые должны быть исправлены на этапе разработки, а не обработаны в production коде.

Когда используются Runtime исключения? | PrepBro