246 votes

Exception levée à l'intérieur du bloc de prise - sera-t-il rattrapé?

Cela peut sembler une question de programmation 101 et j’avais pensé connaître la réponse, mais j’ai maintenant besoin de vérifier. Dans cette partie de code ci-dessous, l'exception levée dans le premier bloc catch sera-t-elle interceptée par le bloc catch général Exception 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 langues, mais je travaille en Java.

297voto

Chris Jester-Young Points 102876

Non, car le nouveau throw n'est pas directement dans le bloc try .

84voto

Pas de. Il est très facile à vérifier.

public class Catch {
    public static void main(String[] args) {
        try {
            throw new java.io.IOException();
        } catch (java.io.IOException exc) {
            System.err.println("In catch IOException: "+exc.getClass());
            throw new RuntimeException();
        } catch (Exception exc) {
            System.err.println("In catch Exception: "+exc.getClass());
        } finally {
            System.err.println("In finally");
        }
    }
}

Doit imprimer:

Dans les captures IOException: la classe java.io.IOException
Enfin
Exception in thread "main" java.lang.RuntimeException
 à l'Attraper.principale(Capture.java:8)

Techniquement, qui aurait pu être un bug du compilateur, dépendant de l'implémentation, unspeicifed comportement, ou de quelque chose. Cependant, la JLS est assez bien cloué vers le bas et que les compilateurs pourrait assez pour ce genre de choses simples (génériques cas de coin peut être une autre affaire).

Alos remarque, si vous échangez autour des deux blocs catch, il l'habitude de compiler. La deuxième capture serait totalement inaccessible.

Remarque, enfin, est toujours appelée, même si une prise est exécutée. (autres qu'idiot cas, tels que les boucles infinies, de l'attachement à travers les outils de l'interface et de tuer le thread, la réécriture du bytecode, etc.).

32voto

Alex Miller Points 28225

Java Langage de Spécification est dit dans l'article 14.19.1:

Si l'exécution du bloc try se termine brusquement à cause d'un jet d'une valeur V, alors il existe un choix:

  • Si le type à l'exécution de V est assignable à l'Paramètre de toute clause catch du rapport d'essai, puis le premier (à gauche) telle clause catch est sélectionné. La valeur V est attribuée au paramètre de la sélection de la clause catch, et le Bloc de la clause catch est exécuté. Si ce bloc se termine normalement, puis le rapport d'essai se termine normalement; si ce bloc se termine brusquement pour une raison quelconque, alors le rapport d'essai se termine brusquement pour la même raison.

Référence: http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#24134

En d'autres termes, la première catch enveloppant qui peut gérer l'exception, et si une exception est levée de cette pêche, qui n'est pas dans le champ d'application de toute autre prise à l'origine pour les essayer, de sorte qu'ils ne seront pas essayer de le manipuler.

L'une relative et déroutant chose à savoir est que, dans un essai[catch]-enfin de la structure, un bloc finally peut lever une exception et si oui, de toute exception lancée par le bloc try ou catch est perdu. Qui peut être déroutant la première fois que tu le vois.

9voto

Mastergeek Points 135

Si vous voulez lever une exception du bloc catch, vous devez informer votre méthode / classe / etc. qu'il faut jeter cette exception. Ainsi:

 public void doStuff() throws MyException {
    try {
        //Stuff
    } catch(StuffException e) {
        throw new MyException();
    }
}
 

Et maintenant, votre compilateur ne vous hurle pas :)

3voto

Ian P Points 7930

Non - Comme l'a dit Chris Jester-Young, cela sera présenté à la prochaine tentative d'interception dans la hiérarchie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X