Как в Java обработать несколько исключений в одном блоке catch?

«Как в Java обработать несколько исключений в одном блоке catch?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Начиная с Java 7, в одном блоке catch можно перехватывать несколько исключений, разделяя их типы вертикальной чертой |.

Синтаксис:

try {
    // Код, который может выбросить разные исключения
    int num = Integer.parseInt(userInput); // Может выбросить NumberFormatException
    int result = 100 / num; // Может выбросить ArithmeticException
} catch (NumberFormatException | ArithmeticException e) {
    // Обработка для обоих типов исключений
    System.err.println("Некорректный ввод или математическая ошибка: " + e.getMessage());
    logger.log(Level.WARNING, "Ошибка обработки ввода", e);
}

Важные правила:

  1. Несвязанные исключения: Типы в мульти-catch должны быть несовместимыми по присваиванию (не находиться в отношении предок-потомок).
    • Допустимо: catch (IOException | SQLException e)
    • Недопустимо: catch (FileNotFoundException | IOException e) (т.к. FileNotFoundException — потомок IOException).
  2. Final переменная: Переменная исключения (e) является неявно final. Ей нельзя переназначить новое значение внутри блока catch.
  3. Цель использования: Устраняет дублирование кода, когда обработка для разных типов исключений идентична.

Пример с ресурсами и более сложной обработкой:

try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    String line = br.readLine();
    // ... обработка строки
} catch (FileNotFoundException e) {
    System.err.println("Файл не найден.");
} catch (IOException | SecurityException e) {
    // Общая обработка для ошибок ввода/вывода и нарушений безопасности
    System.err.println("Ошибка доступа или чтения файла: " + e.getClass().getSimpleName());
}