Ответ
Исключения в Java делятся на три фундаментальные группы, определяемые их классом-предком и семантикой обработки.
| Группа | Класс-предок | Обработка компилятором | Семантика / Примеры |
|---|---|---|---|
| Проверяемые (Checked) | java.lang.Exception (но не RuntimeException) |
Требует обработки (try-catch) или объявления (throws) |
Восстанавливаемые ошибки внешней логики.IOException, SQLException, ClassNotFoundException. |
| Непроверяемые (Unchecked / Runtime) | java.lang.RuntimeException |
Не требует обязательной обработки | Ошибки программирования или внутренней логики.NullPointerException, IllegalArgumentException, ArrayIndexOutOfBoundsException. |
| Ошибки (Errors) | java.lang.Error |
Не требует (и обычно не обрабатывается) | Критические системные сбои JVM.OutOfMemoryError, StackOverflowError, VirtualMachineError. |
Ключевое отличие: Обязательность обработки
Различие между Checked и Unchecked исключениями — это контракт, обеспечиваемый компилятором.
-
Checked исключения — часть сигнатуры метода. Если метод может выбросить
IOException, он должен объявить это. Вызывающий код вынужден решить: обработать исключение или передать его дальше.// Метод ОБЯЗАН объявить checked исключение public String readFirstLine(String path) throws IOException { return Files.readAllLines(Paths.get(path)).get(0); } // Вызывающий код ОБЯЗАН выбрать: обработать или объявить throws public void processFile() { try { String line = readFirstLine("file.txt"); } catch (IOException e) { // ОБРАБОТАТЬ System.err.println("Не удалось прочитать файл"); } } -
Unchecked исключения не являются частью контракта метода. Их возникновение часто свидетельствует о баге (передан
null, неверный индекс). Компилятор не заставляет вас их обрабатывать, так как корректный код не должен их вызывать.// Никаких throws не требуется, даже если метод может выбросить NPE public int getLength(String str) { return str.length(); // Возможен NullPointerException (unchecked) }
Почему Errors не обрабатывают?
Ошибки типа OutOfMemoryError указывают на проблемы, с которыми приложение обычно не может осмысленно справиться (не хватает памяти всей JVM). Попытка их поймать часто бессмысленна.