Ответ
Иерархия исключений Java построена вокруг класса Throwable и разделена на две основные ветви: Error и Exception. Эта структура позволяет четко классифицировать проблемы по их природе и обязательности обработки.
graph TD
A[Throwable] --> B[Error]
A --> C[Exception]
C --> D[RuntimeException]
C --> E[Проверяемые исключения<br>e.g., IOException, SQLException]
B --> F[VirtualMachineError<br>e.g., OutOfMemoryError]
B --> G[LinkageError<br>e.g., NoClassDefFoundError]
D --> H[NullPointerException]
D --> I[IllegalArgumentException]
D --> J[IndexOutOfBoundsException]
Логика разделения:
-
Errorи его подклассы:- Что это: Критические, непроверяемые ошибки виртуальной машины или системы (например,
OutOfMemoryError,StackOverflowError). - Почему отдельно: Они указывают на проблемы, которые приложение обычно не может и не должно обрабатывать. Восстановление часто невозможно.
- Что это: Критические, непроверяемые ошибки виртуальной машины или системы (например,
-
Exceptionи его подклассы:RuntimeExceptionи его подклассы:- Что это: Непроверяемые исключения, указывающие на ошибки программиста или логики (например,
NullPointerException,IllegalArgumentException). - Почему непроверяемые: Обработка таких исключений в каждом месте была бы слишком обременительной. Их можно предотвратить корректным кодом.
- Что это: Непроверяемые исключения, указывающие на ошибки программиста или логики (например,
- Другие подклассы
Exception(проверяемые исключения):- Что это: Исключительные ситуации, которые программа может и должна обработать (например,
IOException,SQLException). - Почему проверяемые: Компилятор требует их явной обработки (через
try-catch) или объявления в сигнатуре метода (throws). Это гарантирует, что разработчик задумается о восстановлении после ожидаемых внешних проблем.
- Что это: Исключительные ситуации, которые программа может и должна обработать (например,
Пример, иллюстрирующий разницу:
// Проверяемое исключение - компилятор заставит обработать
try {
Files.readAllLines(Paths.get("file.txt"));
} catch (IOException e) { // ОБЯЗАТЕЛЬНАЯ обработка
System.err.println("Файл не найден.");
}
// Непроверяемое исключение (Runtime) - обработка опциональна
String str = null;
// Следующая строка выбросит NullPointerException, но компилятор не требует try-catch.
// System.out.println(str.length());
Итог: Иерархия разделяет ответственность: Error — для JVM, непроверяемые RuntimeException — для программиста, проверяемые Exception — для контролируемого восстановления от внешних ошибок.