из JLS
Об этом можно прочитать в JLS, Блоки и операторы , раздел "14.19.2 Выполнение try-catch-finally". И я цитирую,
Если выполнение блока try завершается внезапно по какой-либо другой причине R, выполняется блок finally. Тогда есть выбор:
- Если блок finally завершается нормально, то оператор try завершается преждевременно по причине R.
- Если блок finally завершается преждевременно по причине S, то оператор try завершается преждевременно по причине S (и причина R отбрасывается). Пример ...
Следовательно, следующее (которое действительно сокращено из кода спрашивающего) завершается с NPE, а не с брошенным ExceptionTest
.
class Phinally
{
static class ExceptionTest extends Exception
{ public ExceptionTest(String message) { super(message); } }
public static void main(String[] args) throws ExceptionTest
{
try {
System.out.println("Foo.");
throw new ExceptionTest("throw from try");
} finally {
throw new NullPointerException("throw from finally");
}
}
}
Боковая панель о try
с ресурсами / блоками ARM
Трудности, возникающие из-за этого в некоторых распространенных случаях, особенно с управлением ресурсами, и требующие вложенных блоков try
/ catch
/ finally
и вложенных в блоки finally
, являются одной из причин "попытки с ресурс "функция в проекте COIN (будет интегрирован в Java" довольно скоро "), о котором вы можете прочитать подробнее здесь .
Это одна из многих веских причин, чтобы тратить время на работу статического анализатора, например PMD , который находит и жалуется на этот тип путаницы - хотя он может не уловить дело в вашем коде, я не уверен.
Статическая проверка
Следите за комментариями от @stacktrace: я выполнил соответствующий код через PMD и FindBugs , пытаясь выполнить оба следующих действия:
finally { throw NullPointerException("Foo"); }
и
finally { Object o = null; System.out.println(o.toString()); }
В первом случае PMD заметил и пожаловался на исключение из условия finally
. FindBugs вообще не жалуется. В последнем случае PMD жаловался на несколько вещей, но не связанных между собой («LocalVariableCouldBeFinal», «StringToString» и «UselessOperationOnImmutable»). Тем не менее, FindBugs заметил и пожаловался на нулевую разыменование. Мораль истории? Запустите PMD и FindBugs!
Относящиеся
Относится к SO: Исключение глотания, выдаваемое в catch / finally . Можно ли избежать такой громоздкой попытки / поймать / наконец ...