Существует большая разница в двух представленных вами фрагментах, например, когда сам блок catch
выдает исключение, блок finally
все равно будет выполняться по своей семантике.
следующий фрагмент печатает "Finally!"
, но не "What about me???"
:
try {
throw null; // throws NullPointerException!
} catch (Exception e) {
int oops = 1/0; // throws ArithmeticException!
} finally {
System.out.println("Finally!"); // still gets executed!
}
System.out.println("What about me???"); // doesn't get executed!
Вообще говоря, finally
блока try
практически всегда выполняется.Нет такой гарантии для любого кода, следующего за блоком try
.
Но что, если мой блок catch
является простым оператором print
?
Все еще нет гарантии , что он не будет throw
что-то.Что-то может пойти не так, например, в конструкции для подробного сообщения об исключении.
Даже если вы приложите все усилия, гарантируйте, что код catch
является "безопасным", а код, следующий за оператором try
, всегда будетпосле этого возникает вопрос «почему?».Зачем избегать finally
, но затем так стараться копировать его семантику?
finally
семантика гарантирована, не требуя бремени доказательства ни со стороны автора, ни со стороны читателя кода.Именно из-за этого идиоматический использует блок finally
для помещения обязательного кода «очистки».Использование finally
гарантирует правильность и улучшает как удобочитаемость, так и читабельность.