2010-05-06 10 views
3

J'ai une chaîne Exception dans laquelle method1 jette une exception à method2 qui jette l'exception sur main. Pour quelque raison, le compilateur me force à traiter l'erreur dans method2 et la marque comme une erreur si je ne le fais pas, indiquant qu'il s'agit d'une exception vérifiée. Mais quand le même Exception est jeté plus bas sur la ligne à main, le compilateur me permet de l'ignorer et n'affiche aucune erreur. L'exception d'origine dans method1 est ParseException, qui est cochée. Mais la méthode a une clause générique throws Exception dans l'en-tête, et le même objet est envoyé à la méthode 2, qui a une clause throws Exception identique. Quand et comment cette exception perd-elle le statut d'être vérifié/attrapé par le compilateur?Les exceptions multi-levées sont-elles vérifiées ou exécutées?

Modifié pour clarifier:

public void method1() throws Exception{ 
    // code that may generate ParseException 
} 

public void method2() throws Exception{ 
    method1(); //compiler error (if the throws clause is left out) 
} 

public static void main(String[] args){ 
    method2(); //ignored by compiler, even though the exception isn't caught or thrown or handled at all 
} 

Edit: tout le monde Désolé, la question a été fondée sur une erreur ... La principale méthode avait en fait une clause throws Exception que je manque. J'ai enlevé cela et le code se comporte maintenant comme prévu. Merci pour votre aide!

+1

Pouvez-vous clarifier? Est-ce que method1 lance le 'ParseException', qui est traité comme une 'Exception' par la méthode 2 et la main? Certaines signatures de méthode et les extraits de code try-catch-throw pourraient aider. – justkt

+1

Le code vaut 10 000 mots. –

+0

est ParseException une classe personnalisée? Si oui, pourriez-vous ajouter cela à votre exemple de code? –

Répondre

6

Le fait qu'une exception soit vérifiée ou non dépend entièrement du type d'exception: Si c'est une RuntimeException ou une sous-classe, elle n'est pas vérifiée; sinon, c'est. (Et oui, RuntimeException est une sous-classe de Exception   — l'un des échecs de la conception de la bibliothèque Java, mais pas le plus important.)

Qu'est-ce que le compilateur vérifie est la signature de la méthode. Donc, l'exception réelle levée n'est pas pertinente (à cette fin). Si les méthodes disent throws Exception alors vous devez attraper Exception dans votre méthode ou déclarer que la méthode throws Exception. Les méthodes doivent toujours utiliser la plus étroite possible throws clause   — par exemple, pasthrows Exception mais throws ParseException.

(je dis « non pertinent (à cette fin) » parce que, bien sûr, l'un des autres choses le compilateur faire est de vérifier que vous ne jetez pas les exceptions qui ne sont pas vérifiés couverts par votre throws article .)

Modifier Le code que vous avez ajouté dans votre édition ne compilera pas: 1. il est d'appeler une méthode d'instance sans une instance, et 2. main doit déclarer qu'il jette Exception.

Ce code permet de résoudre les autres problèmes, et (à juste titre) démontre que la clause main a besoin throws Exception:

public class CheckTest 
{ 
    public static final void main(String[] params) 
    { 
     new CheckTest().method2(); 
    } 

    public void method1() throws Exception{ 
     throw new java.text.ParseException("foo", 2); 
    } 

    public void method2() throws Exception{ 
     this.method1(); 
    } 
} 

Résultat:

CheckTest.java:27: unreported exception java.lang.Exception; must be caught or declared to be thrown 

       new CheckTest().method2(); 
            ^
1 error 
+0

Alors pourquoi la fonction principale est-elle sans manipulation, alors que la méthode 2 exige qu'elle soit traitée? – froadie

+0

@froadie: Ce n'est pas le cas, ce code ne sera pas compilé. –

+0

oups! Je viens de réaliser mon erreur. Il y avait en fait une clause 'throws Exception' dans l'en-tête de main ... Quand j'enlève les erreurs du compilateur que j'attendais, elles apparaissaient. Désolé à ce sujet, merci pour votre aide! – froadie

3

Une exception vérifiée n'arrête pas d'être une exception vérifiée. La façon dont vous pouvez transformer une exception cochée en non cochée consiste à la placer dans un type d'exception RuntimeException et à la relancer.

2

Dans votre cas, il sera Exceptions all the way down au racine de la pile d'appels.Si une méthode est déclarée lancer Exception (ce que les méthodes devraient très rarement faire), la méthode appelante devra soit dire qu'elle lance Exception aussi, ou l'attraper et y faire face.

Édition Comme pour l'exemple dans l'OP édité, cela ne sera pas compilé. Vous pouvez déclarer main pour lancer Exception si vous ne voulez pas traiter avec, cependant.

0

Est-il possible que votre compilateur ne se plaint pas du problème dans main() car il rencontre le problème dans method2() et arrête de vérifier la syntaxe à ce moment-là? Les deux devraient être une erreur. Avez-vous corrigé l'appel en method2() et obtenu une compilation propre?