Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Какие исключения нужно обрабатывать в Java
Иерархия исключений в Java
Все исключения наследуются от класса Throwable, который разделяется на две основные ветки:
Throwable
├── Error (обработка не требуется)
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ └── VirtualMachineError
└── Exception (обработка требуется)
├── Checked Exceptions (должны обрабатываться)
│ ├── IOException
│ ├── SQLException
│ ├── ClassNotFoundException
│ └── ParseException
└── Unchecked Exceptions (Runtime, опциональна обработка)
├── NullPointerException
├── IllegalArgumentException
├── ArrayIndexOutOfBoundsException
└── ClassCastException
1. Checked Exceptions (Проверяемые исключения)
Определение: исключения, которые должны быть обработаны на этапе компиляции. Компилятор заставляет тебя либо перехватить их, либо объявить в throws.
Нужно обрабатывать:
// IOException - при работе с файлами
try {
FileReader reader = new FileReader("file.txt");
int character = reader.read();
} catch (IOException e) {
System.err.println("Ошибка чтения файла: " + e.getMessage());
}
// SQLException - при работе с БД
try {
Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
} catch (SQLException e) {
System.err.println("Ошибка БД: " + e.getSQLState());
}
// ClassNotFoundException - при динамической загрузке классов
try {
Class<?> clazz = Class.forName("com.example.MyClass");
} catch (ClassNotFoundException e) {
System.err.println("Класс не найден: " + e.getMessage());
}
Частые checked exceptions:
- IOException - ошибки ввода-вывода (файлы, сокеты, потоки)
- SQLException - ошибки работы с БД
- ClassNotFoundException - класс не найден при динамической загрузке
- ParseException - ошибка парсинга (даты, чисел)
- ReflectiveOperationException - ошибки рефлексии
- InterruptedException - поток был прерван
2. Unchecked Exceptions (RuntimeException)
Определение: исключения, которые не обязательны к обработке на этапе компиляции. Это ошибки программирования, которые нужно предотвращать.
Обрабатывать опционально, но лучше предотвращать:
// NullPointerException - обращение к null
User user = getUser(id);
if (user != null) { // ПРЕДОТВРАЩЕНИЕ
System.out.println(user.getName());
}
// Или с обработкой (нежелательно)
try {
User user = getUser(id);
System.out.println(user.getName());
} catch (NullPointerException e) {
System.err.println("User is null");
}
// IllegalArgumentException - некорректный аргумент
public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Age must be between 0 and 150");
}
this.age = age;
}
// ArrayIndexOutOfBoundsException - индекс за границами
int[] arr = {1, 2, 3};
if (index >= 0 && index < arr.length) { // ПРЕДОТВРАЩЕНИЕ
int value = arr[index];
}
// ClassCastException - неправильное приведение типов
Object obj = "Hello";
if (obj instanceof String) { // ПРЕДОТВРАЩЕНИЕ
String str = (String) obj;
}
Частые unchecked exceptions:
- NullPointerException - обращение к методу/свойству null объекта
- IllegalArgumentException - некорректный аргумент метода
- IllegalStateException - объект в недопустимом состоянии
- ArrayIndexOutOfBoundsException - индекс массива за границами
- ClassCastException - неправильное приведение типов
- NumberFormatException - ошибка преобразования строки в число
- ArithmeticException - ошибка при вычислениях (деление на 0)
3. Errors (Не обрабатываем)
Определение: серьёзные ошибки JVM, которые почти невозможно восстановить.
// OutOfMemoryError - нет памяти
// StackOverflowError - переполнение стека (бесконечная рекурсия)
// LinkageError - ошибка загрузки класса
// Обрабатывать НЕ рекомендуется, лучше исправить код
private void recursiveMethod() {
recursiveMethod(); // Приведёт к StackOverflowError
}
4. Стратегии обработки исключений
Try-Catch-Finally
try {
// Код, который может выбросить исключение
FileReader reader = new FileReader("data.txt");
} catch (FileNotFoundException e) {
// Специфичная обработка
System.err.println("Файл не найден");
} catch (IOException e) {
// Более общая обработка
System.err.println("Ошибка ввода-вывода");
} finally {
// Выполняется всегда
// Закрытие ресурсов, очистка
}
Try-with-resources (автоматическое закрытие)
// AutoCloseable ресурсы закрываются автоматически
try (FileReader reader = new FileReader("file.txt")) {
int ch;
while ((ch = reader.read()) != -1) {
System.out.print((char) ch);
}
} catch (IOException e) {
System.err.println("Ошибка чтения: " + e.getMessage());
}
Throws (делегирование обработки)
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path);
// ...
// IOException не обрабатывается, передаётся вызывающему коду
}
5. Best Practices
✅ Делай так:
- Лови специфичные исключения (не только Exception)
- Логируй ошибки с полной информацией (stacktrace, контекст)
- Предотвращай unchecked exceptions валидацией входных данных
- Используй try-with-resources для ресурсов
- Создавай собственные исключения для бизнес-логики
❌ Не делай так:
catch (Exception e) {}- ловишь всё подряд- Silent failures - пустые catch блоки
- Игнорирование
InterruptedExceptionв многопоточности - Бросание обобщённых Exception вместо специфичных
Собственные исключения
// Для бизнес-логики приложения
public class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}
public void withdraw(BigDecimal amount) throws InsufficientFundsException {
if (balance.compareTo(amount) < 0) {
throw new InsufficientFundsException("Недостаточно средств");
}
balance = balance.subtract(amount);
}
Заключение
Обрабатывай все checked exceptions (IOException, SQLException и т.д.) — это требование языка. RuntimeException лучше предотвращать, чем ловить. Помни, что исключения — это для исключительных ситуаций, а не для нормального потока управления.