2010-04-19 19 views
1

itérez Fondamentalement dans une liste et,
- méthode Invoke sur le premier objet
- Catch la première exception (si seulement); s'il n'y a plus d'exceptions à attraper, retournez normalement. Sinon, continuez à invoquer la méthode jusqu'à ce que toutes les exceptions soient interceptées.
- Passer à l'objet suivant.Comment faire un bloc try-catch qui continue à appeler une méthode sur un objet jusqu'à ce qu'il n'y a plus d'exceptions pour attraper

Je peux parcourir chaque objet, appeler la méthode et intercepter une exception, mais je ne sais pas comment appeler continuellement la méthode et continuer à intercepter les exceptions.

+3

Qu'entendez-vous par «attraper la première exception, s'il n'y a plus d'exceptions pour attraper ...»? * Une invocation de méthode * ne peut renvoyer qu'une seule exception *, donc "first" et "more" n'ont pas de sens dans le contexte de "invoke method". – erickson

+0

La méthode émet une exception avec plusieurs sous-classes/sous-exceptions. – aperson

Répondre

2

Si vous parlez d'un seul appel de méthode qui déclenche plus d'une exception, cela ne peut pas être fait - peu importe le nombre de fois que vous appelez la méthode, il continuera à lancer la première exception . Vous ne pouvez pas retourner dans la méthode et continuer à courir à partir de là; après avoir jeté une exception, tout est fini.

Mais si vous parlez d'une méthode qui jette parfois des exceptions et parfois ne pas essayer quelque chose comme ceci:

boolean thrown = false; 
do { 
    try { 
     thrown = false; 
     method(); 
    } 
    catch (Exception e) { 
     thrown = true; 
     // Handle as you like 
    } 
} (while thrown); 
+0

"peu importe le nombre de fois que vous appelez la méthode, elle continuera à lancer la première exception" - contre-exemple trivial: 'class Ex {int counter = 5; void throwFive() throws Exception {if (counter--) {lance une nouvelle exception ("boo"); }}} ' –

+0

Pour quelque chose comme ça, voir mon deuxième cas. Voir plus haut dans la phrase que vous avez citée: "Si vous parlez de traiter avec un seul appel de méthode qui jettera plus d'une exception." Par exemple, 'void foo() renvoie Exception {throw new Exception (" one "); throw new Exception ("two");} 'auquel cas il n'y a aucun moyen d'attraper la deuxième exception car elle n'est jamais levée. – Etaoin

+0

Ah je vois maintenant ce que tu voulais dire. Et c'est en effet juste. Désolé pour le malentendu. –

6

Ceci est similaire aux autres réponses, mais sans le drapeau, qui semble comme l'encombrement pour moi. Je ne comprends pas vraiment la question, alors je la jette juste là au cas où cela serait utile.

for (Item item : items) { 
    while (true) { 
    try { 
     item.doSomething(); 
     break; 
    } catch (MyException ex) { 
     log.warn("Something failed.", ex); 
    } 
    } 
} 

Cette approche repose sur le fonctionnement de la déclaration break sans étiquette, qui complète brusquement, quitte ensuite la déclaration while enfermant normalement.


D'après les commentaires suivants, je pense qu'il ya une certaine confusion au sujet de ce que cela signifie quand il y a plusieurs exceptions déclarées à être jeté par une méthode.

Chaque invocation d'une méthode peut être terminée par une seule exception levée. Vous ne pouvez pas reprendre l'invocation là où elle s'est arrêtée et gérer les exceptions suivantes. Par conséquent, si une méthode génère plusieurs exceptions, attrapez un ancêtre commun et passez à l'étape suivante. Par exemple, si une méthode renvoie java.io.EOFExceptionoujava.nio.channels.ClosedChannelException, vous pouvez simplement saisir java.io.IOException car il s'agit d'un ancêtre commun. (Vous pouvez aussi saisir java.lang.Exception ou java.lang.Throwable pour la même raison.) Si vous invoquez à nouveau la méthode dans les mêmes conditions, vous n'aurez plus rien à faire.

Si vous voulez tenter d'invoquer la méthode sur chaque objet, même si certains échouent, utilisez ceci:

for (Item item : items) { 
    try { 
    item.doSomething(); 
    } catch (Exception ex) { /* This could be any common ancestor. */ 
    log.warn("Something failed.", ex); 
    } 
} 
0

Je suppose que vous essayez de effectue une sorte de validation des articles en une liste où les erreurs de validation sont signalées par des exceptions de lancement. Je suppose également que vous essayez de recueillir tous les des erreurs de validation.

La réponse simple est que ce problème ne peut pas être résolu en utilisant cette approche.Pour comprendre pourquoi, jetez un oeil à ceci:

boolean exceptionCaught = false; 
do { 
    try { 
     item.doSomething(); 
    } catch (MyException e) { 
     exceptionCaught = true; 
    } 
} while (exceptionCaught); 

Cela échoue parce que chaque fois que vous appelez item.doSomething() il va lancer une exception exactement au même endroit. Le résultat net est une boucle infinie. Le meilleur que vous pouvez faire avec cette approche est de capturer l'première exception pour chaque item dans la liste.

Alors, comment pouvez-vous réaliser ce que vous essayez d'atteindre? La réponse est que vous devez modifier le code de validation pour utiliser un autre moyen de signaler les erreurs que de lancer des exceptions. Par exemple, vous pouvez changer:

class Item { 
    ... 
    void validate() { 
     if (noHat) { 
      throw new MyException("bad hat"); 
     } 
     if (noPants) { 
      throw new MyException("world-wide pants"); 
     } 
    } 
} 

à quelque chose comme ceci:

class Item { 
    ... 
    void isValid(List<MyException> errors) { 
     boolean ok = true; 
     if (noHat) { 
      errors.add(new MyException("bad hat")); 
      ok = false; 
     } 
     if (noPants) { 
      errors.add(new MyException("world-wide pants")); 
      ok = false; 
     } 
     return ok; 
    } 
} 

Messy hein! Vous pouvez le faire de différentes façons, mais ce style de déclaration d'erreur va toujours être plus compliqué. Mais je ne pense pas qu'il existe un moyen pratique d'éviter le désordre ET capture ALL des erreurs de validation.

0

C'est ce que je comprends.

Vous avez la méthode d'un objet qui peut générer un certain nombre d'exceptions.

Ce que vous voulez faire est de tous les attraper et continuer avec l'objet suivant dans la liste.

Est-ce correct?

Donc, ce serait:

for(YourObject o : yourList) { 
    try { 
     o.thatMethod();//invoke that risky method 
    } catch(SomeExceptionClass sec) { 
     // Do something with that exception 
    } catch(SomeOtherExceptionClass soec) { 
     // Do something with that exception 
    } catch(YetAnotherxceptionClass yaec) { 
     // Do something with that exception 
    } catch(OtherUnRelatedException oue) { 
     // Do something with that exception 
    } 
} 

Lorsque vous faites cela, si l'invocation de thatMethod() lance une exception et cette exception est listé dans la section catch, le flux d'exécution sautera à cette exception et après il continuera au flux normal (qui est la boucle for et continuera avec l'objet suivant)

J'espère que c'est ce dont j'ai besoin. Pour plus d'informations, lire: The catch block dans la section Didacticiel Java Essential classes