Оператор try-catch-finally в Java - Вопросы
Всего: 6 вопросов
1. Как работает конструкция try-catch-finally в Java?
Как работает конструкция try-catch-finally в Java?
В блоке try размещают код, который может выбросить исключение. Если исключение возникло, оставшиеся операторы try пропускаются, а блоки catch проверяются сверху вниз: выполняется только первый, чей тип совпадает с типом исключения или является его суперклассом, остальные пропускаются. Блок finally выполняется после try и catch практически всегда — было исключение или нет, перехвачено оно или нет, — поэтому в нём освобождают ресурсы. Затем выполнение продолжается с оператора, следующего за всей конструкцией (если исключение не было перехвачено — оно после finally уходит вызывающему методу). Перехватывать можно как проверяемые, так и непроверяемые исключения.
2. Можно ли использовать try без catch в Java?
Можно ли использовать try без catch в Java?
Да, если есть блок finally: конструкция try-finally допустима. Она не обрабатывает исключение — оно уходит вызывающему методу, — но гарантирует, что завершающий код в finally выполнится перед этим. Допустимые комбинации: try-catch, try-finally, try-catch-finally и try-with-resources (Java 7+), который может обходиться вообще без catch и finally. Одиночный try { ... } без catch, finally и ресурсов — ошибка компиляции.
3. В каких случаях блок finally не выполняется?
В каких случаях блок finally не выполняется?
Блок finally выполняется практически всегда: после нормального завершения try, после catch, при неперехваченном исключении, при исключении внутри catch и при return, break или continue. Он не выполняется, если в try или catch вызван System.exit() (JVM завершается немедленно), при крахе JVM или принудительном завершении процесса (например, kill -9), если управление не доходит до finally из-за бесконечного цикла или вечной блокировки, а также не гарантирован в daemon-потоке, когда JVM завершает работу.
4. Что вернёт метод, если return есть и в try, и в finally?
Что вернёт метод, если return есть и в try, и в finally?
Значение из finally: try { return 1; } finally { return 2; } вернёт 2. Если try выбросил исключение, return в finally молча отменяет его распространение, и вызывающий код о проблеме не узнает. Если же finally только меняет переменную, результат не изменится: в int x = 1; try { return x; } finally { x = 10; } вернётся 1, потому что значение для return вычисляется и запоминается до выполнения finally (для изменяемого объекта, например списка, изменения его содержимого будут видны). Компилятор разрешает return, break, continue и throw в finally, но так писать не рекомендуется.
5. В каком порядке нужно располагать несколько блоков catch?
В каком порядке нужно располагать несколько блоков catch?
Подклассы исключений должны идти раньше своих суперклассов. Блок catch перехватывает указанный класс и все его подклассы, а выполняется только первый подходящий блок, поэтому catch (ArithmeticException e) после catch (Exception e) стал бы недостижимым — это ошибка компиляции exception ArithmeticException has already been caught. Ещё одно правило: catch для проверяемого исключения (например, IOException), которое код в try выбросить не может, тоже не компилируется; на непроверяемые исключения, Exception и Throwable это правило не распространяется.
6. Что такое multi-catch в Java и какие у него ограничения?
Что такое multi-catch в Java и какие у него ограничения?
Multi-catch (Java 7+) — один блок catch, перехватывающий несколько типов исключений, перечисленных через |: catch (IOException | SQLException e). Он убирает дублирование одинаковых обработчиков. Ограничения: типы не должны быть связаны наследованием (catch (FileNotFoundException | IOException e) не компилируется), а параметр multi-catch неявно final — присвоить ему новое значение нельзя. В обычном catch с одним типом параметр не final и его можно переприсвоить, если он не объявлен final явно.