Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
RuntimeException в Java
RuntimeException — это unchecked exception, которые наследуют от класса RuntimeException. Они не требуют явной обработки (try-catch) и часто указывают на ошибки программиста.
Иерархия Exception в Java
Throwable
├── Error (серьёзные ошибки JVM)
└── Exception
├── Checked Exception (требуют обработки)
│ ├── IOException
│ ├── SQLException
│ └── ...
└── RuntimeException (unchecked)
├── NullPointerException
├── ArrayIndexOutOfBoundsException
├── IllegalArgumentException
└── ...
Основные RuntimeException
1. NullPointerException (NPE)
Одна из самых частых ошибок:
public class NullPointerExceptionExample {
public void process(String data) {
// Ошибка: data может быть null
int length = data.length(); // NPE!
}
// Правильно: проверяй на null
public void processChecked(String data) {
if (data != null) {
int length = data.length();
}
}
// Или используй Optional
public void processOptional(String data) {
Optional.ofNullable(data)
.ifPresent(d -> System.out.println(d.length()));
}
}
2. ArrayIndexOutOfBoundsException
Попытка доступа к элементу вне границ массива:
public class ArrayIndexException {
public void process() {
int[] numbers = {1, 2, 3};
// Ошибка: индекс 5 не существует (макс 2)
int value = numbers[5]; // ArrayIndexOutOfBoundsException!
}
// Правильно
public void processCorrect() {
int[] numbers = {1, 2, 3};
if (5 < numbers.length) {
int value = numbers[5];
}
}
}
3. ClassCastException
Ошибка при неправильном приведении типа:
public class ClassCastExceptionExample {
public void process(Object obj) {
// Опасно: может быть не String
String str = (String) obj; // ClassCastException!
}
// Правильно: проверяй instanceof
public void processChecked(Object obj) {
if (obj instanceof String) {
String str = (String) obj;
}
}
// Java 16+: Pattern Matching
public void processPattern(Object obj) {
if (obj instanceof String str) {
System.out.println(str.length());
}
}
}
4. IllegalArgumentException
Передан неверный аргумент методу:
public class IllegalArgumentExceptionExample {
@Service
public class UserService {
public User createUser(String name, int age) {
// Валидация
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException(
"Name cannot be empty"
);
}
if (age < 0 || age > 150) {
throw new IllegalArgumentException(
"Invalid age: " + age
);
}
return new User(name, age);
}
}
}
5. IllegalStateException
Объект находится в неверном состоянии для выполнения операции:
public class StatefulService {
private boolean initialized = false;
public void execute() {
if (!initialized) {
throw new IllegalStateException(
"Service not initialized. Call init() first."
);
}
// Выполнить операцию
}
public void init() {
initialized = true;
}
}
6. UnsupportedOperationException
Операция не поддерживается:
public class UnmodifiableListExample {
public void process() {
List<String> immutableList =
Collections.unmodifiableList(
Arrays.asList("a", "b", "c")
);
// Ошибка: нельзя модифицировать
immutableList.add("d"); // UnsupportedOperationException!
}
}
7. NumberFormatException
Ошибка при парсинге строки в число:
public class NumberFormatExceptionExample {
public void process() {
String value = "abc";
// Ошибка: "abc" не число
int number = Integer.parseInt(value); // NumberFormatException!
}
// Правильно: обработай исключение
public void processChecked() {
String value = "abc";
try {
int number = Integer.parseInt(value);
} catch (NumberFormatException e) {
System.err.println("Invalid number format: " + value);
}
}
}
8. ConcurrentModificationException
Модификация коллекции во время итерации:
public class ConcurrentModificationExample {
public void badApproach() {
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
// Ошибка: модифицируем во время итерации
for (String item : list) {
if (item.equals("b")) {
list.remove(item); // ConcurrentModificationException!
}
}
}
// Правильно
public void correctApproach() {
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
list.removeIf(item -> item.equals("b"));
}
}
9. ArithmeticException
Математическая ошибка (например, деление на ноль):
public class ArithmeticExceptionExample {
public void divide(int a, int b) {
// Ошибка: деление на ноль
int result = a / b; // ArithmeticException!
}
// Правильно
public void divideChecked(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException(
"Divisor cannot be zero"
);
}
int result = a / b;
}
}
10. NoSuchElementException
Попытка получить элемент, который не существует:
public class NoSuchElementExample {
public void process() {
Optional<String> optional = Optional.empty();
// Ошибка: элемента нет
String value = optional.get(); // NoSuchElementException!
}
// Правильно
public void processChecked() {
Optional<String> optional = Optional.empty();
String value = optional.orElse("default");
}
}
Таблица основных RuntimeException
| Exception | Причина | Пример |
|---|---|---|
| NullPointerException | Null ссылка | obj.method() при obj == null |
| ArrayIndexOutOfBoundsException | Индекс вне границ | arr[10] при length = 5 |
| ClassCastException | Неправильное приведение типа | (String) integerObj |
| IllegalArgumentException | Неверный аргумент | negative age |
| IllegalStateException | Неверное состояние объекта | use before init() |
| UnsupportedOperationException | Операция не поддерживается | add() на unmodifiable list |
| NumberFormatException | Ошибка парсинга числа | Integer.parseInt("abc") |
| ConcurrentModificationException | Модификация во время итерации | list.remove() в for-each |
| ArithmeticException | Математическая ошибка | a / 0 |
| NoSuchElementException | Элемент не найден | list.get(999) |
Лучшие практики
// 1. Не ловите RuntimeException без причины
// Плохо:
try {
doSomething();
} catch (RuntimeException e) {
// Скрывает ошибки
}
// Хорошо:
try {
int value = Integer.parseInt(userInput);
} catch (NumberFormatException e) {
logger.error("Invalid number: {}", userInput, e);
}
// 2. Создавайте собственные RuntimeException для специфичных ошибок
public class BusinessLogicException extends RuntimeException {
public BusinessLogicException(String message) {
super(message);
}
public BusinessLogicException(String message, Throwable cause) {
super(message, cause);
}
}
// 3. Используй fail-fast: валидируй рано
public void processUser(User user) {
if (user == null) {
throw new IllegalArgumentException("User cannot be null");
}
// Продолжай работу
}
Вывод
RuntimeException — это мощный инструмент для обработки ошибок, которые нельзя предусмотреть на этапе компиляции. Используй их правильно: валидируй входные данные, проверяй граничные условия, избегай null ссылок. Помни, что unchecked исключения — это всё равно исключительные ситуации и их нужно обрабатывать осознанно.