Иерархия исключений в Java: Throwable, Error, Exception - Вопросы

Всего: 5 вопросов

1. 

Что такое иерархия исключений в Java и из каких ветвей она состоит?

Иерархия исключений в Java — это дерево классов с корнем java.lang.Throwable. Только объекты Throwable и его наследников можно выбросить через throw и перехватить в catch.

У Throwable два прямых подкласса:

  • Error — серьёзные сбои уровня JVM: OutOfMemoryError, StackOverflowError (оба наследуют VirtualMachineError), NoClassDefFoundError. Обычно их не обрабатывают.
  • Exception — проблемы, которые программа может обработать: IOException, ParseException, SQLException, InterruptedException.

Внутри Exception отдельно стоит ветвь RuntimeException — ошибки в логике программы: NullPointerException, ArithmeticException, ClassCastException, IllegalArgumentException и его наследник NumberFormatException. От положения класса в дереве зависит, проверяемое исключение или нет. Сам Throwable — класс, а не интерфейс: он наследует Object и реализует Serializable.

2. 

Чем проверяемые (checked) исключения отличаются от непроверяемых (unchecked) в Java?

  • Проверяемые (checked) — Exception и все его наследники, кроме ветви RuntimeException: IOException, FileNotFoundException, ParseException, SQLException. Компилятор требует перехватить их или объявить в throws, иначе ошибка unreported exception ... must be caught or declared to be thrown. Причина обычно внешняя: файл, сеть, БД, формат входных данных.
  • Непроверяемые (unchecked) — RuntimeException, Error и их наследники: NullPointerException, NumberFormatException, OutOfMemoryError. Код компилируется без обработки. Причина — ошибка программиста (её исправляют проверками в коде) или сбой JVM.

Поэтому Integer.parseInt("abc") компилируется без try-catch (NumberFormatException наследует RuntimeException), а NumberFormat.getInstance().parse("abc") — нет (ParseException наследует Exception напрямую). Сам класс Exception — проверяемый. Деление на checked и unchecked существует только для компилятора: во время выполнения JVM обрабатывает оба вида одинаково.

3. 

Чем Error отличается от Exception и почему catch (Exception e) не перехватывает StackOverflowError?

Error описывает сбои JVM, которые программа обычно не может исправить: закончилась память (OutOfMemoryError), переполнился стек (StackOverflowError). Exception — предсказуемые проблемы, которые код может обработать: файл не найден, строка не является числом.

Error и Exception — соседние ветви иерархии, общий предок у них только Throwable. Поэтому catch (Exception e) пропускает StackOverflowError и OutOfMemoryError: ошибка проходит мимо и завершает программу. Поймать её может catch (StackOverflowError e), catch (Error e) или catch (Throwable e).

Синтаксически перехват Error разрешён, но восстановиться после него удаётся редко. Такой catch используют разве что для логирования и корректного завершения, а перехват Throwable «на всякий случай» — частая ошибка: он глушит и сбои JVM.

4. 

Какие исключения чаще всего встречаются в Java и что их вызывает?

  • NullPointerException (unchecked) — вызов метода или обращение к полю через null. С Java 15 сообщение подробное: Cannot invoke "String.length()" because ... is null.
  • ArrayIndexOutOfBoundsException (unchecked) — индекс массива меньше 0 или не меньше длины: Index 4 out of bounds for length 3.
  • ArithmeticException (unchecked) — целочисленное деление на ноль: / by zero.
  • ClassCastException (unchecked) — приведение объекта к несовместимому типу; компилятор его пропускает, ошибка видна только при выполнении.
  • NumberFormatException (unchecked, наследник IllegalArgumentException) — Integer.parseInt() получил не число: For input string: "abc".
  • IOException, FileNotFoundException (checked) — ошибка ввода-вывода, файл не найден.
  • StackOverflowError, OutOfMemoryError (Error) — бесконечная рекурсия и нехватка памяти в куче (Java heap space).
5. 

Какие основные методы есть у класса Throwable?

Методы Throwable наследуют все исключения и ошибки, подклассы вроде Exception почти ничего к ним не добавляют:

  • getMessage() — описание исключения или null; getLocalizedMessage() по умолчанию возвращает то же самое.
  • toString() — имя класса и сообщение: java.lang.NumberFormatException: For input string: "abc". Вызывается, когда исключение передают в println().
  • getCause() — исключение-причина или null; initCause() задаёт причину, если её не передали в конструктор (повторный вызов — IllegalStateException).
  • getStackTrace() — массив StackTraceElement[]; в элементе [0] — метод, где было выброшено исключение.
  • printStackTrace() — выводит трассу стека в System.err (есть перегрузки для PrintStream и PrintWriter).
  • getSuppressed() — подавленные исключения, например возникшие при закрытии ресурсов в try-with-resources (Java 7+).
Страница 1 из 1