Является ли блок finally без блока catch анти-паттерном Java? - PullRequest
44 голосов
/ 02 марта 2009

У меня был довольно болезненный опыт устранения неполадок при поиске и устранении неисправностей в некотором коде, который выглядел следующим образом:

try {
   doSomeStuff()
   doMore()
} finally {
   doSomeOtherStuff()
}

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

Если бы код сказал это вместо этого, проблема была бы очевидна:

try {
    doSomeStuff()
    doMore()
} catch (Exception e) {
    log.error(e);
} finally {
   doSomeOtherStuff()
}

Итак, мой вопрос таков:

Является ли блок finally без какого-либо блока catch известным анти-паттерном Java? (Это, безусловно, не совсем очевидный подкласс явно известного анти-паттерна «Не глотай исключения!»)

Ответы [ 12 ]

0 голосов
/ 12 октября 2009

Try / Наконец - это способ правильно освободить ресурсы. Код в блоке finally НИКОГДА не должен выдаваться, поскольку он должен воздействовать только на ресурсы или состояние, которые были получены до входа в блок try.

Кроме того, я думаю, что log4J является почти анти-паттерном.

ЕСЛИ ВЫ ХОТИТЕ ПРОВЕРИТЬ РАБОЧУЮ ПРОГРАММУ, ИСПОЛЬЗУЙТЕ ПРАВИЛЬНЫЙ ИНСПЕКЦИОННЫЙ ИНСТРУМЕНТ (т. Е. Отладчик, IDE или, в крайнем смысле, ткачику байт-кода, но НЕ ЗАДАВАЙТЕ ЗАЯВЛЕНИЯ О РЕГИСТРАЦИИ В КАЖДОЙ НЕСКОЛЬКО ЛИНИЙ!)

В двух приведенных вами примерах первый выглядит правильно. Второй включает код логгера и содержит ошибку. Во втором примере вы подавляете исключение, если выдается одно из первых двух утверждений (т.е. вы перехватываете его и регистрируете, но не перебрасываете. Это то, что я нахожу очень распространенным в использовании log4j, и это реальная проблема разработки приложения. По сути, с вашим изменением вы заставляете программу терпеть неудачу так, что системе будет очень трудно ее обработать, так как вы в основном идете вперед, как будто у вас никогда не было исключений (вроде VB basic на error возобновить следующую конструкцию).

0 голосов
/ 02 марта 2009

Я думаю, что попытка без улова - это анти-паттерн. Использование try / catch для обработки исключительных условий (ошибки ввода-вывода файла, время ожидания сокета и т. Д.) Не является антишаблоном.

Если вы используете try / finally для очистки, рассмотрите вариант использования блока.

...