Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Unchecked Исключение (Unchecked Exception)
Определение
Unchecked исключение (или runtime исключение) — это исключение, которое не обязательно перехватывать или объявлять в сигнатуре метода. Компилятор Java не проверяет, обработано ли такое исключение. Unchecked исключение наследуется от класса RuntimeException.
Основное назначение
1. Различие между Checked и Unchecked исключениями
// CHECKED исключение (наследуется от Exception, но НЕ RuntimeException)
public class FileNotFoundException extends IOException { }
// Компилятор ТРЕБУЕТ обработку
public void readFile() throws FileNotFoundException { // Обязательно throws
throw new FileNotFoundException("File not found");
}
// UNCHECKED исключение (наследуется от RuntimeException)
public class InvalidAgeException extends RuntimeException { }
// Компилятор НЕ требует обработки
public void setAge(int age) { // Можно БЕЗ throws
if (age < 0) {
throw new InvalidAgeException("Age cannot be negative");
}
}
2. Иерархия исключений
Throwable
├── Error (серьёзные ошибки JVM)
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ └── VirtualMachineError
│
└── Exception
├── CHECKED исключения (наследуют Exception напрямую)
│ ├── IOException
│ ├── SQLException
│ ├── FileNotFoundException
│ └── ...
│
└── RuntimeException (UNCHECKED исключения)
├── NullPointerException
├── ArrayIndexOutOfBoundsException
├── IllegalArgumentException
├── ArithmeticException
├── ClassCastException
└── ...
3. Когда использовать Unchecked исключения
Unchecked исключение для ошибок программиста:
// NullPointerException — ошибка программиста (забыл проверить null)
public String getName(User user) {
return user.getName(); // Если user == null, то NPE (unchecked)
}
// ArrayIndexOutOfBoundsException — ошибка программиста (неправильный индекс)
public int getElement(int[] arr, int index) {
return arr[index]; // Если index >= arr.length, то исключение (unchecked)
}
// IllegalArgumentException — некорректный аргумент
public void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Age must be positive");
}
this.age = age;
}
Checked исключение для ошибок окружения:
// IOException — ошибка окружения (файла или сети)
public String readFile(String path) throws IOException {
FileReader reader = new FileReader(path); // Требует обработки
// ...
}
// SQLException — ошибка окружения (БД недоступна)
public List<User> getAllUsers() throws SQLException {
Connection conn = getConnection(); // Требует обработки
// ...
}
4. Преимущества Unchecked исключений
Чистый код:
// С UNCHECKED исключениями
public int divide(int a, int b) {
return a / b; // ArithmeticException если b==0 (unchecked)
}
// Vs с CHECKED исключениями (переусложненно)
public int divide(int a, int b) throws DivisionByZeroException {
if (b == 0) throw new DivisionByZeroException();
return a / b;
}
// Вызывающий код
try {
int result = divide(10, 0);
} catch (DivisionByZeroException e) {
// Обработка
}
Распространение ошибки:
// Unchecked исключения распространяются автоматически
public User getUser(int id) { // Нет throws
User user = findById(id);
if (user == null) {
throw new IllegalArgumentException("User not found"); // NPE распространится
}
return user;
}
// Вызывающий код может обработать или нет
User user = getUser(1); // Без try-catch
try {
user = getUser(1);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
5. Создание собственного Unchecked исключения
// Наследуем от RuntimeException (не от Exception!)
public class InsufficientBalanceException extends RuntimeException {
public InsufficientBalanceException(String message) {
super(message);
}
public InsufficientBalanceException(String message, Throwable cause) {
super(message, cause);
}
}
public class BankAccount {
private double balance;
public void withdraw(double amount) {
if (amount > balance) {
throw new InsufficientBalanceException(
"Balance is " + balance + ", requested " + amount
); // Не требует throws в сигнатуре
}
balance -= amount;
}
}
// Использование
BankAccount account = new BankAccount(100);
account.withdraw(50); // OK
account.withdraw(60); // Throws InsufficientBalanceException
6. Примеры Unchecked исключений
// NullPointerException
String name = null;
int length = name.length(); // NPE!
// ArrayIndexOutOfBoundsException
int[] arr = {1, 2, 3};
int value = arr[10]; // IndexOutOfBoundsException!
// ArithmeticException
int result = 10 / 0; // ArithmeticException!
// ClassCastException
Object obj = "string";
Integer num = (Integer) obj; // ClassCastException!
// IllegalArgumentException
Thread thread = new Thread(null); // IllegalArgumentException!
// IllegalStateException
List<Integer> list = Collections.unmodifiableList(new ArrayList<>());
list.add(1); // UnsupportedOperationException!
// NumberFormatException
int num = Integer.parseInt("abc"); // NumberFormatException!
7. Сравнение Checked vs Unchecked
| Параметр | Checked | Unchecked |
|---|---|---|
| Наследник | Exception | RuntimeException |
| Проверка компилятором | Да (обязательно) | Нет |
| throws в сигнатуре | Обязателен | Не требуется |
| try-catch | Обязателен | Опционален |
| Использование | Ошибки окружения | Ошибки программиста |
| Пример | IOException | NullPointerException |
8. Обработка Unchecked исключений
// Опция 1: Не обрабатывать (распространяется вверх)
public void process() {
String str = null;
str.length(); // NPE распространится
}
// Опция 2: Перехватить и обработать
public void process() {
try {
String str = null;
str.length();
} catch (NullPointerException e) {
System.out.println("Got NPE: " + e);
}
}
// Опция 3: Перехватить и обернуть
public void process() throws CustomException {
try {
String str = null;
str.length();
} catch (NullPointerException e) {
throw new CustomException("Processing failed", e);
}
}
// Опция 4: Лучший подход — предотвратить
public void process(String str) {
if (str == null) {
throw new IllegalArgumentException("String cannot be null");
}
str.length();
}
9. Лучшие практики
ДА — используй Unchecked для:
// Ошибки программиста
if (user == null) {
throw new IllegalArgumentException("User cannot be null");
}
if (age < 0) {
throw new IllegalArgumentException("Age must be positive");
}
if (items.isEmpty()) {
throw new IllegalStateException("Items list is empty");
}
НЕТ — не используй Unchecked для:
// Ошибки окружения должны быть CHECKED
public void readFile(String path) {
// НЕПРАВИЛЬНО:
// throw new RuntimeException("File not found"); // Плохо!
// ПРАВИЛЬНО:
// throws IOException { // Хорошо!
// FileReader reader = new FileReader(path);
// }
}
Выводы
Unchecked исключение нужно для:
- Обозначения ошибок программиста, которые можно было предотвратить
- Избежания переусложнения API checked исключениями
- Распространения исключений без боязни забыть обработать
- Указания на то, что ошибка логическая, а не внешняя
Оно НЕ заменяет Checked исключения, а дополняет их для разных сценариев. Правило простое: ошибки окружения → checked, ошибки программиста → unchecked.