На какие группы делятся исключения в Java?

Ответ

В Java исключения иерархически делятся на три основные группы:

1. Проверяемые исключения (Checked Exceptions)

  • Наследуются от класса java.lang.Exception (но не от RuntimeException).
  • Компилятор требует их обязательной обработки через try-catch или объявления в сигнатуре метода (throws).
  • Используются для ожидаемых ошибок, от которых можно восстановиться (например, проблемы ввода-вывода, отсутствие файла).
  • Примеры: IOException, SQLException, FileNotFoundException.
try {
    FileReader reader = new FileReader("file.txt");
} catch (FileNotFoundException e) { // Обработка проверяемого исключения
    System.err.println("Файл не найден: " + e.getMessage());
}

2. Непроверяемые исключения (Unchecked Exceptions / Runtime Exceptions)

  • Наследуются от класса java.lang.RuntimeException.
  • Компилятор не требует их обязательной обработки.
  • Возникают из-за ошибок программирования (логические ошибки, неправильное использование API).
  • Примеры: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException.

3. Ошибки (Errors)

  • Наследуются от класса java.lang.Error.
  • Указывают на критические проблемы в среде выполнения JVM, от которых приложение обычно не может или не должно восстанавливаться.
  • Примеры: OutOfMemoryError, StackOverflowError, VirtualMachineError.

Пользовательские исключения создаются путем наследования от Exception (проверяемые) или RuntimeException (непроверяемые).

Ответ 18+ 🔞

Вот же ж, ну и тема, аж вспотеть можно. Слушай, давай разберёмся в этой иерархии исключений, а то у некоторых от неё волосы дыбом встают, как от приведения ночью в сортире.

Представь себе, что твой код — это такой многоэтажный дом. Исключения — это всё, что может пойти не по плану: от соседа, который залил тебя сверху, до того, что фундамент вдруг треснул.

1. Проверяемые исключения (Checked Exceptions) — это как предсказуемый пиздец. Эти ребята наследуются от Exception, но не от RuntimeException. Компилятор — тот самый занудный прораб — смотрит на тебя в упор и говорит: «Мужик, я вижу, ты тут файл собрался читать. А если его нет? Ты че, дебил? Обработай это, блядь, или в сигнатуре объяви, что ты не отвечаешь!». То есть, ты обязан либо поймать их в try-catch, либо выкинуть дальше через throws.

  • Зачем нужны: Для ситуаций, которые, в принципе, могут случиться в рабочей программе, и от которых можно как-то отстроиться. Файл не нашли? Спросим у пользователя путь ещё раз. Сеть упала? Попробуем переподключиться.
  • Примеры: IOException, SQLException. Классика жанра.
try {
    FileReader reader = new FileReader("file.txt"); // Опа, щас кинет
} catch (FileNotFoundException e) { // Ловим эту манду
    System.err.println("Файл не найден, ёпта: " + e.getMessage()); // И не паникуем
}

2. Непроверяемые исключения (Runtime Exceptions) — это ошибки программиста, тупость в чистом виде. Родня RuntimeException. Компилятор на них смотрит сквозь пальцы: «Ну, раз ты такой умный — сам разбирайся». Они возникают из-за косяков в логике. Обрабатывать их глобально — можно, но чаще всего они означают, что ты где-то накосячил и надо чинить код, а не ловить исключение.

  • Зачем нужны: Чтобы показать тебе, что ты — мудак. Обратился к null? Получи NullPointerException. Полез за границы массива? На, держи ArrayIndexOutOfBoundsException. Сам виноват, идиот.

3. Ошибки (Errors) — это пиздец абсолютный, конец света в JVM. Наследники Error. Это уже не твои косяки, это жопа на уровне виртуальной машины. Память кончилась (OutOfMemoryError), стек переполнился (StackOverflowError). Восстанавливаться? Да ты шутишь. Обычно тут уже только креститься и перезапускать приложение.

А если своих захочу? Захотел своих демонов — пожалуйста! Наследуйся от Exception — получишь проверяемое, и все будут обязаны с ним считаться. Наследуйся от RuntimeException — получишь непроверяемое, и все будут материться, когда оно вылезет в runtime. Всё просто, как три копейки.

Короче, суть в чём: проверяемые — для ожидаемых проблем среды (файлов, сети), непроверяемые — для твоих личных ляпов, ошибки — для тотального краха системы. Распределил — и живи спокойно.