Ответ
В Java все ошибки и исключения организованы в иерархию, корнем которой является класс Throwable. Понимание этой иерархии критично для корректной обработки ошибок.
graph TD
A[Throwable] --> B[Error]
A --> C[Exception]
B --> B1[VirtualMachineError]
B1 --> B2[OutOfMemoryError]
B1 --> B3[StackOverflowError]
B --> B4[LinkageError]
C --> D[IOException]
D --> D1[FileNotFoundException]
C --> E[RuntimeException]
E --> E1[NullPointerException]
E --> E2[IllegalArgumentException]
E --> E3[IndexOutOfBoundsException]
C --> F[Прочие проверяемые исключения<br/>например, SQLException]
Ключевые ветви иерархии:
-
Errorи его подклассы:- Представляют критические системные ошибки, от которых приложение обычно не может восстановиться (например, нехватка памяти, сбой JVM).
- Обрабатывать их, как правило, не нужно и не рекомендуется.
- Примеры:
OutOfMemoryError,StackOverflowError,NoClassDefFoundError.
-
Exceptionи его подклассы:-
Представляют исключительные ситуации, с которыми приложение может и должно уметь работать.
-
Делится на две основные категории:
-
Проверяемые исключения (Checked Exceptions):
- Наследуются от
Exception, но НЕ отRuntimeException. - Компилятор требует их обработки (через
try-catch) или объявления в сигнатуре метода (throws). - Примеры:
IOException,SQLException,ClassNotFoundException. - Используются для ожидаемых ошибок внешних условий (файл не найден, сетевой сбой).
- Наследуются от
-
Непроверяемые исключения (Unchecked Exceptions):
- Наследуются от
RuntimeException. - Компилятор не проверяет их обработку.
- Примеры:
NullPointerException,IllegalArgumentException,ArrayIndexOutOfBoundsException. - Обычно указывают на ошибки программирования (баги в коде).
- Наследуются от
-
Пример обработки с учётом иерархии:
try {
// Код, который может выбросить разные исключения
someRiskyOperation();
} catch (FileNotFoundException e) {
// Обработка конкретного проверяемого исключения
System.out.println("Файл не найден: " + e.getMessage());
} catch (IOException e) {
// Более общая обработка всех IO-исключений
System.out.println("Ошибка ввода-вывода: " + e.getMessage());
} catch (IllegalArgumentException e) {
// Обработка непроверяемого исключения
System.out.println("Неверный аргумент: " + e.getMessage());
} catch (Exception e) {
// Универсальный обработчик для всех оставшихся Exception
System.out.println("Произошла ошибка: " + e.getMessage());
} // Error-ы здесь не ловятся, и это правильно.