← Назад к вопросам

Какие исключения нужно обрабатывать

2.0 Middle🔥 111 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Какие исключения нужно обрабатывать в 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 лучше предотвращать, чем ловить. Помни, что исключения — это для исключительных ситуаций, а не для нормального потока управления.