Какова иерархия классов исключений (exceptions) в 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());
}

Ответ 18+ 🔞

Да ты посмотри на эту хуйню, на эту иерархию исключений в 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 (Ошибки): Это, блядь, не исключения, а пиздец полный. Непроверяемые, да. Это когда у тебя JVM накрылась медным тазом, память кончилась или стек переполнился. Ты их обычно не ловишь — что ты, блядь, с OutOfMemoryError сделаешь? Поймаешь и что? Память из жопы достанешь? Это конец, приехали.

2. Exception (Исключения): А вот тут уже интереснее, две банды:

  • Проверяемые (Checked): Это те, что не от RuntimeException. Компилятор, сука, как занудная тёща — требует, чтобы ты их либо в try-catch обернул, либо в объявлении метода через throws выпятил. Типа, «я предупреждён, мать его». Это обычно внешние проблемы: файл не найдись, сеть отвалилась, база данных глюкнула. IOException, SQLException — вот эти все пидарасы.
  • Непроверяемые (Unchecked): А это уже наследнички RuntimeException. Компилятор на них, в принципе, похуй, не требует обязательной поимки. А почему? Да потому что это чаще всего твои собственные косяки, ёпта! NullPointerException — это ты на null полез, мудак. 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());
}

Вот и вся магия. Одни исключения — как предсказуемые проблемы, которые надо предусмотреть. Другие — как пиздец, от которого не спастись. А третьи — как пиздюлина от самого себя, которую можно и проигнорировать, пока не прилетело в ебало.