Исключения в Java
Исключение — это объект, который Java создаёт и пробрасывает вверх по стеку вызовов, когда обычный ход выполнения нарушается: не открылся файл, разыменован null, кончилась память. Метод, который не может справиться с ситуацией, не возвращает код ошибки — он бросает исключение, и управление немедленно переходит к ближайшему подходящему catch, разматывая стек по пути. Если такого обработчика нет, поток завершается, а трассировка печатается в консоль.
Ключевое, что Java отделяет от простого «случилась ошибка»: часть исключений компилятор заставляет вас предусмотреть в момент компиляции (проверяемые), а часть — нет (непроверяемые). От этого деления зависит, где вы обязаны написать catch или throws, а где ошибка честно «прострелит» до самого верха. Ещё две вещи почти всегда идут в комплекте: разница между throw (бросить сейчас) и throws (объявить в сигнатуре) и конструкция try-with-resources, которая закрывает ресурсы за вас. Полная карта — в слоях ниже.
Карта темы
- Checked и unchecked — подклассы
ExceptionпротивRuntimeExceptionиError; кого компилятор заставляет обработать, а кого нет. - throw и throws — оператор, который возбуждает исключение, против части сигнатуры, которая его объявляет.
- try-with-resources — автоматический вызов
close()в обратном порядке,AutoCloseableи подавленные исключения.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
Считать Error и RuntimeException проверяемыми | Компилятор не требует их объявлять; throws для них не нужен |
Ловить широкое Exception пустым catch, чтобы «заглушить» компилятор | Ошибка теряется без обработки — баг всплывёт позже и без следа |
Писать throws в теле метода, а throw — в сигнатуре | Путаница оператора и части объявления: код не скомпилируется |
Освобождать файл или поток в finally вручную вместо try-with-resources | Легко забыть close() или потерять исходное исключение под сбоем закрытия |
| Ждать, что ресурсы закроются в порядке открытия | try-with-resources закрывает их в ОБРАТНОМ порядке |
| Использовать исключения для обычного потока управления | fillInStackTrace при конструировании обходит весь стек — на порядки медленнее ветвления |
Значение для собеседований
Исключения спрашивают почти на каждом Java-интервью, но проверяют не список подклассов, а модель: что компилятор заставляет предусмотреть, кто отвечает за освобождение ресурсов и чем «бросить» отличается от «объявить».
Что обычно проверяют:
- Деление на проверяемые и непроверяемые и где оно проходит по иерархии классов.
- Разницу между
throwиthrows. - Что делает try-with-resources и какой интерфейс нужен ресурсу.
- Порядок закрытия ресурсов и что такое подавленное исключение.
- Почему исключения дороги как замена обычной проверки условия.
Типичный неверный ответ: «RuntimeException — проверяемое, для него нужен throws». Это открывает разговор о том, что проверяемость определяется местом в иерархии (Exception без RuntimeException), а не серьёзностью, и что компилятор ничего не требует для RuntimeException и Error.