Обработка исключений в Java - Вопросы
Всего: 6 вопросов
1. Что такое исключение в Java и чем оно отличается от ошибки компиляции?
Что такое исключение в Java и чем оно отличается от ошибки компиляции?
Исключение — это объект подкласса Throwable, который создаётся в момент сбоя во время выполнения программы: деление целого числа на ноль, вызов метода у null, отсутствующий файл, неверный формат числа. Объект хранит тип исключения, сообщение и стек вызовов (stack trace).
Ошибку компиляции (пропущенная точка с запятой, несовместимые типы вроде int x = "5";) находит компилятор javac, и программа просто не запускается. Исключения возникают только при выполнении уже скомпилированного кода, поэтому try-catch от ошибок компиляции не спасает.
2. Как работает обработка исключений в Java: куда передаётся управление после исключения?
Как работает обработка исключений в Java: куда передаётся управление после исключения?
Метод, в котором возникло исключение, прекращает выполнение. JVM ищет подходящий блок catch сначала в текущем методе, затем в вызвавшем его, и так далее вверх по стеку вызовов. Первый подходящий обработчик получает объект исключения, и программа продолжается сразу после этой конструкции try-catch.
try {
subRoutine(); // внутри: int a = 10 / 0;
System.out.println("Не выполнится");
} catch (ArithmeticException e) {
System.out.println("Перехвачено: " + e.getMessage());
}
// Вывод: Перехвачено: / by zero
Возобновления в Java нет: к строке, где произошёл сбой, выполнение не возвращается, оставшиеся строки блока try и всех прерванных методов пропускаются. Если операцию нужно повторить, try оборачивают в цикл.
3. Что происходит, если исключение никто не перехватил, и как читать stack trace?
Что происходит, если исключение никто не перехватил, и как читать stack trace?
Если ни в одном методе стека вызовов нет подходящего catch, срабатывает обработчик по умолчанию: он печатает стек вызовов и завершает поток, в котором возникло исключение.
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ExceptionExample1.subRoutine(ExceptionExample1.java:8)
at ExceptionExample1.main(ExceptionExample1.java:3)
Stack trace читают сверху вниз: первая строка — тип и сообщение исключения, вторая — место, где оно возникло (метод и номер строки), ниже — кто вызвал этот метод. Причину бага обычно ищут в самой верхней строке at ..., которая указывает на ваш код.
4. Чем проверяемые (checked) исключения отличаются от непроверяемых (unchecked)?
Чем проверяемые (checked) исключения отличаются от непроверяемых (unchecked)?
Все исключения наследуются от Throwable, у которого две ветви: Error и Exception. Проверяемость решает подкласс RuntimeException:
- Checked —
Exceptionи его подклассы, кромеRuntimeException(IOException,SQLException,ParseException). Компилятор требует перехватить их вcatchили объявить вthrows, иначе ошибка компиляции. - Unchecked —
RuntimeExceptionи его подклассы (ArithmeticException,NullPointerException,NumberFormatException), обычно сигнализируют об ошибках в логике программы; обработка не обязательна. - Error (
OutOfMemoryError,StackOverflowError) — тоже unchecked, это серьёзные сбои уровня JVM, их обычно не перехватывают.
5. Кто генерирует исключения в Java: JVM или сама программа?
Кто генерирует исключения в Java: JVM или сама программа?
И та, и другая:
- JVM автоматически выбрасывает исключение при нарушении правил языка:
ArithmeticException(целочисленное деление на ноль),ArrayIndexOutOfBoundsException,NullPointerException,ClassCastException— без единой строки кода с вашей стороны. - Библиотеки JDK выбрасывают исключения оператором
throwвнутри стандартных классов:Integer.parseInt("abc")→NumberFormatException, чтение отсутствующего файла →NoSuchFileExceptionилиFileNotFoundException(подклассыIOException). - Ваш код выбрасывает исключение, когда данные неверны с точки зрения бизнес-логики:
throw new IllegalArgumentException("Возраст не может быть отрицательным").
6. Какие ошибки чаще всего допускают новички при обработке исключений?
Какие ошибки чаще всего допускают новички при обработке исключений?
- «Проглоченное» исключение —
catch, который ничего не сообщает:catch (NumberFormatException e) { return 0; }. ДляparseAge("abc")метод молча вернёт 0, и программа продолжит работать с неверными данными. Если метод не может осмысленно обработать ошибку, пусть сообщит о ней вызывающему коду:throw new IllegalArgumentException("Некорректный возраст: " + input, e); - Потеря причины — новое исключение в
catchбез передачиeобрывает цепочкуCaused by, и исходный стек вызовов пропадает. catch (Exception e)на всякий случай — перехватывает и ожидаемые сбои, и баги вродеNullPointerException, которые лучше увидеть и исправить. Перехватывайте самый конкретный тип.- Исключения вместо проверок — ловить
ArrayIndexOutOfBoundsExceptionвместо проверкиi < array.lengthмедленнее и хуже читается. Исключения — для исключительных ситуаций, а не для обычного ветвления.