exceção de perda na captura de bloco

Eu corro este código:

public class User { public static void main(String args[]) { int array[] = new int[10]; int i = 1; try { System.out.println("try: " + i++); System.out.println(array[10]); System.out.println("try"); } catch (Exception e) { System.out.println("catch: " + i++); System.out.println(array[10]); System.out.println("catch"); } finally { System.out.println("finally: " + i++); Object o = null; o.hashCode(); System.out.println("finally"); } } } 

Resultado:
tente: 1
pegar: 2
finalmente: 3
Exceção no thread “main” java.lang.NullPointerException em user.main (User.java:17)

em block catch – ArrayIndexOutOfBoundsException, mas perdemos essa exceção, por quê?

Do JLS

Você pode ler sobre isso no JLS, Blocos e Extratos , seção “14.19.2 Execução do try-catch-finally”. E eu cito

Se a execução do bloco try for concluída abruptamente por qualquer outro motivo R, o bloco finally será executado. Então há uma escolha:

  • Se o bloco finally for concluído normalmente, a instrução try será concluída abruptamente pela razão R.
  • Se o bloco finally for concluído abruptamente pela razão S, então a instrução try será concluída abruptamente pela razão S (e a razão R será descartada). O exemplo…

Portanto, o seguinte (que é realmente condensado do código do questionador) é concluído com um NPE, não o ExceptionTest lançado.

 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"); } } } 

Uma barra lateral sobre try with resources / ARM blocks

Dificuldades em raciocinar sobre isso em alguns casos comuns, especificamente com o gerenciamento de resources e a necessidade de blocos nested try / catch / finally e nested inside finally , são parte do motivo do recurso “try with resource” no projeto COIN (para ser integrado Java “bastante em breve”), sobre o qual você pode ler mais sobre aqui .

Esta é uma das muitas boas razões para investir tempo na execução de um analisador estático como o PMD , que encontra e reclama desse tipo de confusão – embora possa não entender o caso em seu código, não tenho certeza.

Verificação estática

Acompanhar o comentário do @stacktrace: eu corri o código relevante através do PMD e FindBugs , tentando ambos os seguintes:

 finally { throw NullPointerException("Foo"); } 

e

 finally { Object o = null; System.out.println(o.toString()); } 

Para o primeiro, a PMD percebeu e reclamou de uma exceção sendo lançada de uma cláusula finally . FindBugs não reclame de todo. Para o último, PMD reclamou várias coisas, mas nada relacionado (“LocalVariableCouldBeFinal”, “StringToString” e “UselessOperationOnImmutable”). No entanto, o FindBugs notou e reclamou sobre um desreferenciamento nulo. Moral da história? Execute o PMD e o FindBugs!

Relacionado

Relacionado com SO: exceção de deglutição lançada em catch / finally . Posso evitar essa tentativa complicada / pegar / finalmente …

Você acabou de encontrar um recurso estranho do Java, que se o bloco finally não terminar corretamente, ele ocultará quaisquer exceções que foram lançadas anteriormente.

Isso é por design, não é um erro.

Sua última exceção não ocorre dentro de um bloco try { } catch { } , então não há catch { } ou, finally { } processamento.