Недавно я был удивлен, обнаружив, что в блоке finally в Java возможно иметь оператор return.
Похоже, что многие люди думают, что это плохо, как описано в « Не возвращайся в конце предложения ». Немного углубившись в подробности, я также обнаружил, что «возвращение Java не всегда » показывает довольно ужасные примеры других типов управления потоками в блоках finally.
Итак, мой вопрос: может ли кто-нибудь привести мне пример, когда оператор return (или другой элемент управления потоком) в блоке finally создает лучший / более читаемый код?
источник
У меня было ДЕЙСТВИТЕЛЬНО трудное время, чтобы отследить ошибку, которая была вызвана этим. Код был что-то вроде:
Случилось так, что исключение было сгенерировано в каком-то другом коде. Он был пойман и зарегистрирован и переброшен в рамках
somethingThatThrewAnException()
метода. Но исключение не распространялось в прошломproblemMethod()
. После долгого времени просмотра мы наконец отследили его до метода return. Метод return в блоке finally в основном останавливал распространение исключения, которое произошло в блоке try, даже если оно не было перехвачено.Как уже говорили другие, хотя и законно возвращаться из блока finally в соответствии со спецификацией Java, это ПЛОХАЯ вещь, и ее не следует делать.
источник
Javac предупредит о возвращении в конце, если вы используете -Xlint: наконец. Первоначально javac не выдавал предупреждений - если что-то не так с кодом, он не должен компилироваться. К сожалению, обратная совместимость означает, что непредвиденная глупость не может быть запрещена.
Исключения могут быть выброшены из блоков finally, но в этом случае демонстрируемое поведение почти наверняка соответствует вашим ожиданиям.
источник
Добавление управляющих структур и возврат к блокам finally {} - это еще один пример злоупотреблений «просто потому, что вы можете», которые распространены практически на всех языках разработки. Джейсон был прав, предполагая, что он легко может стать кошмаром обслуживания - аргументы против раннего возврата из функций более применимы к этому случаю «позднего возврата».
Наконец, существуют блоки для одной цели, чтобы вы могли полностью привести себя в порядок, независимо от того, что произошло во всем предыдущем коде. В основном это закрытие / освобождение файловых указателей, соединений с базой данных и т. Д., Хотя я мог видеть, что это растягивается, чтобы добавить добавление в сделанный на заказ аудит.
Все, что влияет на возврат функции, должно лежать в блоке try {}. Даже если у вас есть метод, с помощью которого вы проверяете внешнее состояние, выполняете трудоемкую операцию, а затем снова проверяете это состояние в случае, если оно становится недействительным, вы все равно хотели бы провести вторую проверку внутри попытки {} - если бы она находилась внутри, наконец, {} и длительная операция завершилась неудачно, вы бы без необходимости проверяли это состояние во второй раз.
источник
Простой Groovy тест:
Вывод:
Вопрос:
Одним интересным моментом для меня было посмотреть, как Groovy справляется с неявными доходами. В Groovy можно «вернуться» из метода, просто оставив значение в конце (без возврата). Как вы думаете, что произойдет, если вы раскомментируете строку runningThreads.remove (..) в операторе finally - это перезапишет обычное возвращаемое значение («ОК») и охватит исключение ?!
источник
Возвращение изнутри
finally
блока приведетexceptions
к потере.Оператор return внутри блока finally приведет к тому, что любое исключение, которое может быть сгенерировано в блоке try или catch, будет отброшено.
Согласно спецификации языка Java:
Примечание. Согласно JLS 14.17 оператор возврата всегда завершается преждевременно.
источник