Eu tenho um pequeno problema teórico com construções try-catch.
Ontem fiz um exame prático sobre Java e não entendo o seguinte exemplo:
try {
try {
System.out.print("A");
throw new Exception("1");
} catch (Exception e) {
System.out.print("B");
throw new Exception("2");
} finally {
System.out.print("C");
throw new Exception("3");
}
} catch (Exception e) {
System.out.print(e.getMessage());
}
A pergunta era "como será a saída?"
Eu tinha certeza que seria AB2C3, mas surpresa surpresa, não é verdade.
A resposta certa é ABC3 (testado e realmente é assim).
Minha pergunta é: para onde foi a exceção ("2")?
print(e.getMessage())
:). Você pensou que a saída seriaAB2C3
: você achou que ocatch
bloco mais externo seria executado duas vezes?Respostas:
Na especificação da linguagem Java 14.20.2. :
Portanto, quando há um bloco catch que lança uma exceção:
mas também há um bloco finalmente que também gera uma exceção:
Exception("2")
será descartado e somenteException("3")
será propagado.fonte
return
declarações. Se o seu bloco finalmente tiver um retorno, ele substituirá qualquer retorno em umtry
oucatch
bloco. Por causa desses "recursos", uma boa prática é que finalmente o bloco nunca deve lançar uma exceção ou ter uma declaração de retorno.As exceções lançadas no bloco finalmente suprimem a exceção lançada anteriormente no bloco try ou catch.
Exemplo do Java 7: http://ideone.com/0YdeZo
Do exemplo de Javadoc :
A nova
try-with
sintaxe do Java 7 adiciona outra etapa de supressão de exceção: as exceções lançadas no bloco try suprimem as lançadas anteriormente na parte try-with.do mesmo exemplo:
No código da pergunta, cada bloco descarta claramente a exceção antiga, nem mesmo registra, não é boa quando você está tentando resolver alguns erros:
http://en.wikipedia.org/wiki/Error_hiding
fonte
Como
throw new Exception("2");
é jogado docatch
bloco e nãotry
, ele não será pego novamente.Veja 14.20.2. Execução de tentar finalmente e tentar pegar finalmente .
Isto é o que está acontecendo:
fonte
Sua pergunta é muito óbvia e a resposta é simples na mesma extensão. O objeto Exception com a mensagem "2" é substituído pelo objeto Exception com a mensagem como "3".
Explicação: Quando ocorre uma exceção, seu objeto é lançado para pegar o bloco a ser manipulado. Mas quando ocorre uma exceção no próprio bloco catch, seu objeto é transferido para o bloco OUTER CATCH (se houver) para tratamento de exceção. E o mesmo aconteceu aqui. O objeto de exceção com a mensagem "2" é transferido para o bloco catch externo. Mas espere .. Antes de sair do bloco try-catch interno, ele deve executar finalmente. Aqui ocorreu a mudança com a qual estamos preocupados. Um novo objeto EXCEPTION (com a mensagem "3") é jogado fora ou esse bloco finalmente substitui o objeto de exceção já lançado (com a mensagem "2"). Como resultado, quando a mensagem do objeto de exceção é impressa, obtemos valor substituído, ou seja, "3" e não "2".
Lembre-se: Apenas um objeto de exceção pode ser tratado no bloco CATCH.
fonte
O
finally
bloco sempre corre. Vocêreturn
de dentro do bloco try ou uma exceção é lançada. A exceção lançada nofinally
bloco substituirá a lançada no ramo catch.Além disso, lançar uma exceção não causará nenhuma saída por si só. A linha
throw new Exception("2");
não escreverá nada.fonte
De acordo com o seu código:
Como você pode ver aqui:
# 1
;B - # 2
;# 3
executado após a instrução try-catch (ou apenas try, se não houver nenhuma exceção) e imprimeC - # 4
e lança uma nova exceção;# 5
;Resultado é
ABC3
. E2
é omitido da mesma maneira que1
fonte