J'ai un petit problème théorique avec les constructions try-catch.
J'ai passé hier un examen pratique sur Java et je ne comprends pas l'exemple suivant:
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());
}
La question était "à quoi ressemblera la sortie?"
J'étais à peu près sûr que ce serait AB2C3, MAIS surprise surprise, ce n'est pas vrai.
La bonne réponse est ABC3 (testé et c'est vraiment comme ça).
Ma question est la suivante: où est passée l'exception («2»)?
print(e.getMessage())
. Vous pensiez que la sortie seraitAB2C3
: pensez-vous que lecatch
bloc le plus à l'extérieur serait exécuté deux fois?Réponses:
À partir de la spécification du langage Java 14.20.2. :
Donc, quand il y a un bloc catch qui lève une exception:
mais il y a aussi un bloc finally qui lève également une exception:
Exception("2")
seront rejetés et seulsException("3")
seront propagés.la source
return
déclarations. Si votre bloc finally a un retour, il remplacera tout retour dans un bloctry
oucatch
. En raison de ces "fonctionnalités", une bonne pratique est que le bloc finally ne doit jamais lever d'exception ou avoir une instruction de retour.Les exceptions levées dans le bloc finally suppriment l'exception lancée plus tôt dans le bloc try ou catch.
Exemple Java 7: http://ideone.com/0YdeZo
De l' exemple de Javadoc :
La nouvelle
try-with
syntaxe de Java 7 ajoute une autre étape de suppression des exceptions: les exceptions levées dans le bloc try suppriment celles lancées plus tôt dans la partie try-with.du même exemple:
Dans le code à partir de la question, chaque bloc rejette clairement l'ancienne exception, sans même la consigner, ce qui n'est pas bon lorsque vous essayez de résoudre certains bogues:
http://en.wikipedia.org/wiki/Error_hiding
la source
Puisqu'il
throw new Exception("2");
est jeté ducatch
bloc et nontry
, il ne sera plus rattrapé.Voir 14.20.2. Exécution de try-finally et try-catch-finally .
Voici ce qui se passe:
la source
Votre question est très évidente, et la réponse est simple dans la même mesure. L'objet Exception avec le message "2" est écrasé par l'objet Exception avec le message comme "3".
Explication: Lorsqu'une exception se produit, son objet est renvoyé pour attraper le bloc à gérer. Mais lorsqu'une exception se produit dans le bloc catch lui-même, son objet est transféré vers OUTER CATCH Block (le cas échéant) pour la gestion des exceptions. Et la même chose s'est produite ici. L'objet d'exception avec le message "2" est transféré vers OUTER catch Block. Mais attendez ... Avant de quitter le bloc try-catch interne, il DOIT EXÉCUTER ENFIN. C'est là que s'est produit le changement qui nous préoccupe. Un nouvel objet EXCEPTION (avec le message "3") est jeté ou ce bloc finally qui a remplacé l'objet Exception déjà lancé (avec le message "2"). En conséquence, lorsque le message de l'objet Exception est imprimé, nous avons obtenu valeur remplacée, c'est-à-dire "3" et non "2".
Gardez à l'esprit: un seul objet d'exception peut être géré par un bloc CATCH.
la source
Le
finally
bloc s'exécute toujours. Soit vousreturn
de l'intérieur du bloc try, soit une exception est levée. L'exception lancée dans lefinally
bloc remplacera celle lancée dans la branche catch.De plus, lever une exception ne provoquera aucune sortie en soi. La ligne
throw new Exception("2");
n'écrira rien.la source
Selon votre code:
Comme vous pouvez le voir ici:
# 1
;B - # 2
;# 3
s'exécute finalement après l'instruction try-catch (ou seulement try, si aucune exception ne s'est produite) et afficheC - # 4
et lève une nouvelle exception;# 5
;Le résultat est
ABC3
. Et2
est omis de la même manière que1
la source