Cela peut sembler être une question de programmation 101 et j'avais pensé connaître la réponse, mais j'ai maintenant besoin de vérifier. Dans ce morceau de code ci-dessous, l'exception lancée dans le premier bloc catch sera-t-elle interceptée par le bloc général Exception catch ci-dessous?
try {
// Do something
} catch(IOException e) {
throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
// Will the ApplicationException be caught here?
}
J'ai toujours pensé que la réponse serait non, mais maintenant j'ai un comportement étrange qui pourrait être causé par cela. La réponse est probablement la même pour la plupart des langages mais je travaille en Java.
Réponses:
Non, puisque le nouveau
throw
n'est pastry
directement dans le bloc.la source
RuntimeException
est renvoyé ducatch
bloc, il n'y aura pas d'erreur de compilation.catch
clause d' exception parent est répertoriée avant unecatch
clause d' exception enfant . Je crois comprendre que Java interdit cela et qu'il est intercepté au moment de la compilation.Non, c'est très facile à vérifier.
Devrait imprimer:
Techniquement, cela aurait pu être un bogue du compilateur, un comportement dépendant de l'implémentation, un comportement non spécifié ou quelque chose. Cependant, le JLS est assez bien défini et les compilateurs sont assez bons pour ce genre de chose simple (le cas du coin des génériques peut être une autre affaire).
Notez également que si vous permutez les deux blocs catch, il ne se compilera pas. La deuxième capture serait complètement inaccessible.
Notez que le bloc finally s'exécute toujours même si un bloc catch est exécuté (sauf dans les cas idiots, comme les boucles infinies, l'attachement via l'interface des outils et la suppression du thread, la réécriture du bytecode, etc.).
la source
finally
est, bien sûr, d'appelerSystem.exit
. :-Pfor(;;);
est plus court, contenu dans la langue, n'introduit pas beaucoup d'effets secondaires et, pour moi, plus évident.System.exit
est plus convivial pour le processeur! : -O Mais oui, d'accord, c'est clairement un critère subjectif. De plus, je ne savais pas que vous étiez un golfeur de code. ;-)La spécification du langage Java dit dans la section 14.19.1:
Référence: http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#24134
En d'autres termes, la première capture englobante qui peut gérer l'exception le fait, et si une exception est levée hors de cette capture, ce n'est pas dans la portée de toute autre capture pour l'essai d'origine, donc ils n'essaieront pas de la gérer.
Une chose connexe et déroutante à savoir est que dans une structure try- [catch] -finally, un bloc finally peut lever une exception et si c'est le cas, toute exception levée par le bloc try ou catch est perdue. Cela peut être déroutant la première fois que vous le voyez.
la source
try
-with-resources. Ensuite, sitry
ET lesfinally
deux lancent,finally
est supprimé, mais est également AJOUTÉ à l'exception detry
. Sicatch
vous lancez également, vous n'avez pas de chance, à moins que vous ne gériez cela vous-même via 'addSuppressed' et en ajoutant l'try
exception - alors vous avez les trois.Si vous voulez lever une exception du bloc catch, vous devez informer votre méthode / classe / etc. qu'il a besoin de lever ladite exception. Ainsi:
Et maintenant, votre compilateur ne vous criera plus dessus :)
la source
Non - Comme Chris Jester-Young l'a dit, il sera jeté au prochain essai dans la hiérarchie.
la source
Comme dit ci-dessus ...
j'ajouterais que si vous avez du mal à voir ce qui se passe, si vous ne pouvez pas reproduire le problème dans le débogueur, vous pouvez ajouter une trace avant de relancer la nouvelle exception (avec le bon vieux système .out.println au pire, avec un bon système de journalisation comme log4j sinon).
la source
Il ne sera pas attrapé par le deuxième bloc catch. Chaque exception est interceptée uniquement à l'intérieur d'un bloc try. Vous pouvez cependant imbriquer des essais (ce n'est pas une bonne idée en général):
la source
Non, puisque les captures se réfèrent toutes au même bloc try, donc lancer depuis un bloc catch serait intercepté par un bloc try englobant (probablement dans la méthode qui a appelé celui-ci)
la source
Ancien message, mais la variable "e" doit être unique:
la source