Какой базовый механизм обработки исключений (exception handling) в Java?

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

Ответ

Базовый механизм строится на трех ключевых блоках: try, catch, finally и ключевых словах throw и throws.

1. Блок try-catch-finally:

try {
    // Код, который может вызвать исключение (опасная операция)
    FileInputStream fis = new FileInputStream("file.txt");
    int data = fis.read();
} catch (FileNotFoundException e) {
    // Обработка конкретного checked-исключения
    System.err.println("Файл не найден: " + e.getMessage());
} catch (IOException e) {
    // Обработка более общего checked-исключения
    System.err.println("Ошибка ввода-вывода: " + e.getMessage());
} catch (Exception e) {
    // "Корзинка" для любых других исключений (не рекомендуется для повседневного использования)
    System.err.println("Неизвестная ошибка: " + e);
} finally {
    // Блок выполняется ВСЕГДА, даже если было исключение или return
    // Используется для освобождения ресурсов (закрытие файлов, соединений)
    if (fis != null) {
        try { fis.close(); } catch (IOException e) { /* логирование */ }
    }
}

2. Классификация исключений:

  • Checked Exceptions (Exception): Компилятор обязывает их обрабатывать (try-catch) или объявлять в сигнатуре метода (throws). Пример: IOException, SQLException. Представляют ожидаемые ошибки внешних условий.
  • Unchecked Exceptions (RuntimeException): Не требуют обязательной обработки. Пример: NullPointerException, IllegalArgumentException, ArithmeticException. Чаще всего указывают на ошибки программиста.
  • Error: Критические системные ошибки, которые обычно не обрабатываются (например, OutOfMemoryError, StackOverflowError).

3. Проброс исключений (throws):

public void readFile() throws FileNotFoundException, IOException {
    // Метод не обрабатывает исключения, а передает их вызывающему коду
    FileInputStream fis = new FileInputStream("file.txt");
    // ...
}

4. Выброс исключения (throw):

if (value < 0) {
    throw new IllegalArgumentException("Значение не может быть отрицательным: " + value);
}

Best Practice: Всегда старайтесь обрабатывать исключения на том уровне, где есть достаточно информации для принятия осмысленного решения (логирование, повторная попытка, возврат пользователю понятной ошибки).