Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Иерархия ошибок в Java
Иерархия ошибок (Exception Hierarchy) — это структурированная система классов для обработки исключительных ситуаций в Java. Вся иерархия строится на базовом классе Throwable и его подклассах.
Общая структура иерархии
Throwable
├── Error
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ ├── VirtualMachineError
│ └── IOError
└── Exception
├── IOException
├── SQLException
├── RuntimeException
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ ├── IllegalArgumentException
│ ├── ClassCastException
│ ├── ArithmeticException
│ └── UnsupportedOperationException
├── FileNotFoundException
├── InterruptedException
└── Custom Exceptions
Класс Throwable — корень иерархии
Throwable — это суперкласс всех ошибок и исключений. Содержит основные методы:
public class Throwable implements Serializable {
// Получить сообщение об ошибке
public String getMessage() { ... }
// Вывести stack trace в консоль
public void printStackTrace() { ... }
// Вернуть строку со всей информацией
public String toString() { ... }
// Получить причину (корневую ошибку)
public Throwable getCause() { ... }
// Установить причину
public Throwable initCause(Throwable cause) { ... }
// Получить массив элементов стека
public StackTraceElement[] getStackTrace() { ... }
}
Error — необратимые ошибки
Error — это серьёзные проблемы на уровне JVM, которые приложение не должно обрабатывать. Если Error возник, приложение должно завершиться.
// OutOfMemoryError — недостаточно памяти
public void problemWithMemory() {
List<byte[]> list = new ArrayList<>();
while (true) {
list.add(new byte[1024 * 1024]); // Выделяем по 1MB
// java.lang.OutOfMemoryError: Java heap space
}
}
// StackOverflowError — переполнение стека вызовов
public void infiniteRecursion() {
infiniteRecursion(); // Бесконечная рекурсия
// java.lang.StackOverflowError
}
Основные типы Error:
- OutOfMemoryError — память полностью заполнена
- StackOverflowError — стек вызовов переполнен
- VirtualMachineError — ошибка JVM
- IOError — критическая ошибка ввода-вывода
- NoClassDefFoundError — класс не найден при запуске
Exception — обрабатываемые исключения
Exception — это исключения, которые приложение может и должно обрабатывать. Это нормальные ошибки работы программы.
Checked exceptions (проверяемые исключения)
Checked exceptions — это исключения, которые нужно обрабатывать или объявлять. Компилятор требует явную обработку.
// IOException — проверяемое исключение
public void readFile(String filename) throws IOException {
FileReader reader = new FileReader(filename);
// Нужно либо обработать, либо объявить throws
}
// SQLException — проверяемое исключение
public void queryDatabase() throws SQLException {
Connection conn = DriverManager.getConnection("jdbc:...");
// Нужна обработка или throws
}
// Правильная обработка
public void readFileWithHandling(String filename) {
try {
FileReader reader = new FileReader(filename);
// Чтение файла
} catch (FileNotFoundException e) {
System.err.println("Файл не найден: " + e.getMessage());
} catch (IOException e) {
System.err.println("Ошибка чтения: " + e.getMessage());
}
}
Основные checked exceptions:
import java.io.*;
import java.sql.*;
// I/O операции
try {
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
// Может выбросить IOException
} catch (FileNotFoundException e) {
System.err.println("Файл не найден");
} catch (IOException e) {
System.err.println("Ошибка чтения файла");
}
// Работа с БД
try {
Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
// Может выбросить SQLException
} catch (SQLException e) {
System.err.println("Ошибка БД: " + e.getMessage());
}
// Работа с потоками
try {
Thread.sleep(1000);
// Может выбросить InterruptedException
} catch (InterruptedException e) {
System.err.println("Поток прерван");
Thread.currentThread().interrupt();
}
Unchecked exceptions (непроверяемые исключения)
Unchecked exceptions (подклассы RuntimeException) — это исключения, которые не обязательно обрабатывать. Компилятор не требует явной обработки.
// NullPointerException — непроверяемое
public void processString(String str) {
int length = str.length(); // Если str == null, выбросит NPE
// Не требует throws
}
// ArrayIndexOutOfBoundsException — непроверяемое
public void accessArray(int[] arr, int index) {
int value = arr[index]; // Если index >= arr.length
// Не требует throws
}
// IllegalArgumentException — непроверяемое
public void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("Возраст не может быть отрицательным");
}
}
// ClassCastException — непроверяемое
public void castObject(Object obj) {
String str = (String) obj; // Если obj не String
// Не требует throws
}
Основные unchecked exceptions:
// NullPointerException — обращение к null
String name = null;
name.length(); // NPE
// ArrayIndexOutOfBoundsException — индекс вне границ
int[] arr = {1, 2, 3};
int val = arr[10]; // ArrayIndexOutOfBoundsException
// ArithmeticException — ошибка арифметики
int result = 10 / 0; // ArithmeticException: / by zero
// ClassCastException — неправильное приведение типов
Object obj = "Hello";
Integer num = (Integer) obj; // ClassCastException
// IndexOutOfBoundsException — индекс вне границ (Collections)
List<String> list = new ArrayList<>();
String item = list.get(5); // IndexOutOfBoundsException
// IllegalStateException — неправильное состояние объекта
Connection conn = getConnection();
conn.close();
conn.createStatement(); // IllegalStateException
// UnsupportedOperationException — операция не поддерживается
List<String> list = Collections.unmodifiableList(new ArrayList<>());
list.add("item"); // UnsupportedOperationException
Создание своих исключений
// Базовое checked исключение
public class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(String message, double amount) {
super(message);
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
// Использование
public void withdraw(double amount) throws InsufficientFundsException {
if (balance < amount) {
throw new InsufficientFundsException(
"Недостаточно средств",
amount - balance
);
}
balance -= amount;
}
// Обработка
try {
account.withdraw(500);
} catch (InsufficientFundsException e) {
System.out.println("Ошибка: " + e.getMessage());
System.out.println("Не хватает: " + e.getAmount());
}
// Базовое unchecked исключение
public class ValidationException extends RuntimeException {
public ValidationException(String message) {
super(message);
}
public ValidationException(String message, Throwable cause) {
super(message, cause);
}
}
// Использование
if (age < 0 || age > 150) {
throw new ValidationException("Некорректный возраст: " + age);
}
Обработка множественных исключений
// Java 7+: multi-catch
try {
// какой-то код
} catch (IOException | SQLException | InterruptedException e) {
System.err.println("Произошла ошибка: " + e.getMessage());
e.printStackTrace();
}
// try-with-resources (автоматическое закрытие ресурсов)
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("Ошибка чтения файла");
}
Сравнение checked и unchecked
| Характеристика | Checked | Unchecked |
|---|---|---|
| Базовый класс | Exception (но не RuntimeException) | RuntimeException |
| Обязательна обработка | Да | Нет |
| Требует throws | Да | Нет |
| Контроль компилятора | Да | Нет |
| Примеры | IOException, SQLException | NullPointerException, IllegalArgumentException |
Правильное использование иерархии ошибок делает код более надёжным и предсказуемым. Checked exceptions помогают не забыть об обработке критических ошибок, а unchecked exceptions позволяют писать более чистый код для программных ошибок.