Обработка исключений в Java - Вопросы

Всего: 6 вопросов

1. 

Что такое исключение в Java и чем оно отличается от ошибки компиляции?

Исключение — это объект подкласса Throwable, который создаётся в момент сбоя во время выполнения программы: деление целого числа на ноль, вызов метода у null, отсутствующий файл, неверный формат числа. Объект хранит тип исключения, сообщение и стек вызовов (stack trace).

Ошибку компиляции (пропущенная точка с запятой, несовместимые типы вроде int x = "5";) находит компилятор javac, и программа просто не запускается. Исключения возникают только при выполнении уже скомпилированного кода, поэтому try-catch от ошибок компиляции не спасает.

2. 

Как работает обработка исключений в 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?

Если ни в одном методе стека вызовов нет подходящего 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)?

Все исключения наследуются от 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 или сама программа?

И та, и другая:

  • 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 медленнее и хуже читается. Исключения — для исключительных ситуаций, а не для обычного ветвления.
Страница 1 из 1