Вопрос-ответ

Returning from a finally block in Java

Возврат из блока finally в Java

Недавно я был удивлен, обнаружив, что в блоке finally в Java возможно иметь оператор return.

Похоже, многие люди думают, что делать так, как описано в 'Не возвращать в предложении finally', - это плохо. Копнув немного глубже, я также нашел 'Возврат Java не всегда', который показывает несколько довольно ужасных примеров других типов управления потоком в блоках finally.

Итак, мой вопрос в том, может ли кто-нибудь привести мне пример, когда оператор return (или другой элемент управления потоком) в блоке finally создает лучший / более читаемый код?

Переведено автоматически
Ответ 1

Мне было ОЧЕНЬ сложно отследить ошибку много лет назад, которая была вызвана этим. Код был примерно таким:

Object problemMethod() {
Object rtn = null;
try {
rtn = somethingThatThrewAnException();
}
finally {
doSomeCleanup();
return rtn;
}
}

Произошло то, что исключение было сгенерировано в каком-то другом коде. Оно перехватывалось, регистрировалось и повторно создавалось в somethingThatThrewAnException() методе. Но исключение не распространялось дальше problemMethod(). После ДОЛГОГО изучения этого мы, наконец, отследили его до метода return . Метод return в блоке finally в основном останавливал распространение исключения, которое произошло в блоке try, даже если оно не было перехвачено.

Как говорили другие, хотя возврат из блока finally законен в соответствии со спецификацией Java, это ПЛОХО, и этого не следует делать.

Ответ 2

Приведенные вами примеры являются достаточной причиной для того, чтобы не использовать управление потоком из finally.

Даже если есть надуманный пример, где это "лучше", подумайте о разработчике, которому позже придется поддерживать ваш код и который может не знать тонкостей. Этим плохим разработчиком можете быть даже вы....

Ответ 3

javac предупредит о возврате в finally, если вы используете -Xlint:finally . Изначально javac не выдавал никаких предупреждений - если что-то не так с кодом, он не сможет скомпилироваться. К сожалению, обратная совместимость означает, что непредвиденная изобретательная глупость не может быть запрещена.

Исключения могут создаваться из блоков finally, но в этом случае показанное поведение почти наверняка является тем, что вы хотите.

Ответ 4

Добавление управляющих структур и возврат к блокам finally{} - это всего лишь еще один пример злоупотреблений "просто потому, что вы можете", которые распространены практически во всех языках разработки. Джейсон был прав, предположив, что это может легко стать кошмаром для обслуживания - аргументы против досрочного возврата из функций в большей степени применимы к этому случаю "позднего возврата".

Блоки Finally существуют с одной целью, чтобы позволить вам полностью навести порядок за собой, независимо от того, что произошло во всем предшествующем коде. В основном это закрытие / освобождение указателей файлов, подключений к базе данных и т.д., Хотя я мог видеть, что это растягивается, чтобы сказать добавление в индивидуальный аудит.

Все, что влияет на возврат функции, должно находиться в блоке try{} . Даже если бы у вас был метод, с помощью которого вы проверяли внешнее состояние, выполняли трудоемкую операцию, затем снова проверяли это состояние на случай, если оно стало недействительным, вам все равно потребовалась бы вторая проверка внутри try{} - если бы она находилась внутри finally{} и длительная операция завершилась неудачей, вам пришлось бы проверять это состояние второй раз без необходимости.

java exception