Какова иерархия классов исключений (exceptions) в Java?

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

Ответ

Иерархия исключений в Java основана на классе Throwable и делится на две основные ветви: Error и Exception. Ключевое различие — в их природе и необходимости обработки.

graph TD
    A[Throwable] --> B[Error]
    A --> C[Exception]
    C --> D[RuntimeException]
    C --> E[Checked Exceptions]

    B --> F[OutOfMemoryError]
    B --> G[StackOverflowError]
    B --> H[VirtualMachineError]

    D --> I[NullPointerException]
    D --> J[IllegalArgumentException]
    D --> K[ArrayIndexOutOfBoundsException]

    E --> L[IOException]
    E --> M[SQLException]
    E --> N[ClassNotFoundException]

1. Error (Ошибки):

  • Непроверяемые (unchecked).
  • Критические проблемы, которые приложение обычно не может или не должно обрабатывать (например, сбой JVM).
  • Примеры: OutOfMemoryError, StackOverflowError, LinkageError.

2. Exception (Исключения):

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

Пример обработки:

try {
    // Код, который может выбросить проверяемое исключение
    FileInputStream fis = new FileInputStream("file.txt"); // Может выбросить FileNotFoundException (checked)
    int data = fis.read();
} catch (FileNotFoundException e) { // Обработка конкретного проверяемого исключения
    System.err.println("Файл не найден: " + e.getMessage());
} catch (IOException e) { // Обработка более общего проверяемого исключения
    System.err.println("Ошибка ввода-вывода: " + e.getMessage());
} catch (RuntimeException e) { // Обработка непроверяемых исключений (опционально, но полезно)
    System.err.println("Неожиданная ошибка выполнения: " + e.getMessage());
}