Почему закрывающий блок finally не должен выходить с оператором throw?

Я делаю обзор кода с помощью Jtest. В отчете JTest говорится, что закрывающий блок finally не должен выходить с оператором throw. В чем причина? И как я могу это исправить? Я обертываю исключение в пользовательское исключение, и у метода есть броски.

Коды выглядит так:

public HashMap methodName(Connection conn, HashMap hMap) throws MyCustomException {
 try
 {}
 catch(SQLException)
 {}
 catch(Exception)
 {}
 finally
 {
   try
   {}
   catch(SQLException e)
   {
     mLog.fatal("Error Msg", e);
     throw new MyCustomException("msg", e);
   }
 }
}

2 ответа

Это скроет оригинальное исключение.

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

Вы хотите бросить окончательное исключение вообще?

Отказ от этого делает вещи намного проще и часто является правильным решением.

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

Но, возможно, вы решите по-другому: если что-то пойдет не так в finally блок, вы видите, что как таковой отказ methodName() позвоните, что вы должны сообщить об этом как сбой для вашего абонента. Тогда вы можете получить два конкурирующих исключения, и вам нужно решить, какое из них бросить вашему звонящему. И вы должны войти в другой, чтобы он не был полностью потерян.

Как правило, основная часть является более интересной, но она не так легко доступна: вам нужно ввести переменную Exception вне блока try-catch-finally, инициализируемого нулем, где вы храните любое исключение основной части, чтобы вы могли может бросить тот из блока наконец. Полученный код будет странным...

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

Это связано с тем, что создание исключения в блоке finally приведет к дальнейшему распространению исключения (за пределами блока try-catch). Это в некотором смысле противоречит цели блока try catch. Однако могут быть случаи, когда это действительно может помочь.

Другие вопросы по тегам