Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Когда использовать 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 коде.