web-dev-qa-db-fra.com

Catch une exception générique en Java?

Nous utilisons JUnit 3 au travail et il n'y a pas d'annotation ExpectedException. Je voulais ajouter un utilitaire à notre code pour envelopper ceci:

 try {
     someCode();
     fail("some error message");
 } catch (SomeSpecificExceptionType ex) {
 }

Alors j'ai essayé ceci:

public static class ExpectedExceptionUtility {
  public static <T extends Exception> void checkForExpectedException(String message, ExpectedExceptionBlock<T> block) {
     try {
        block.exceptionThrowingCode();
        fail(message);
    } catch (T ex) {
    }
  }
}

Cependant, Java ne peut pas utiliser de types d'exception génériques dans un bloc catch, je pense.

Comment puis-je faire quelque chose comme ça, en contournant la limitation Java?

Existe-t-il un moyen de vérifier que la variable ex est de type T?

34
Alex Baranosky

Vous pouvez passer l'objet Classe et le vérifier par programme.

public static <T extends Exception> void checkForException(String message, 
        Class<T> exceptionType, ExpectedExceptionBlock<T> block) {
    try {
       block.exceptionThrowingCode();
   } catch (Exception ex) {
       if ( exceptionType.isInstance(ex) ) {
           return;
       } else {
          throw ex;  //optional?
       }
   }
   fail(message);
}

//...
checkForException("Expected an NPE", NullPointerException.class, //...

Je ne suis pas sûr que vous souhaitiez ou non le retransmission; le renchérissement échouerait/échouerait également le test, mais je ne le ferais pas du point de vue sémantique, car cela signifie fondamentalement "nous n'avons pas eu l'exception à laquelle nous nous attendions", ce qui représente une erreur de programmation plutôt qu'une erreur d'environnement de test.

28
Mark Peters

Je comprends l’impulsion pour essayer de simplifier votre idiome de test d’exception, mais sérieusement: ne le faites pas. Chaque choix possible que vous proposez est un remède qui est pire que la maladie. Surtout @ExpectedException de JUnit 4! Il s’agit d’une solution framework trop intelligente, qui demande à tout le monde d’apprendre son fonctionnement, par opposition à un peu de code Java classique qui va de soi. Pire encore, cela ne vous donne aucun moyen de n’envelopper que la partie de votre test qui devrait renvoyer l’exception. Ainsi, si une étape de configuration précédente lève cette même exception, votre test réussira même si votre code est cassé.

Je pourrais écrire une longue diatribe à ce sujet ici (je suis désolé de ne pas avoir assez de temps), car nous avons eu une longue discussion à ce sujet entre les ingénieurs de Java ici chez Google, et le consensus était qu'aucune de ces solutions folles valent la peine. Habituez-vous à essayer/attraper, ce n'est vraiment pas si grave.

5
Kevin Bourrillion

Les génériques ne sont pas des types. Ce ne sont pas des modèles. Ce sont des contrôles de type compilation, en Java. Les blocs d’exception s’accrochent au type. Vous pouvez attraper (Exception e) ou même attraper (Throwable e), puis lancer au besoin.

1

Eh bien, vous pouvez simplement attraper Exception et le rediffuser si ce n’est pas une Exception attendue. Bien que les bonnes pratiques de codage stipulent généralement que le chemin du code de réussite ne doit pas être défini par une exception, vous pouvez donc repenser votre conception.

0
ShadowRanger

La clause Catch avec le paramètre type n'est pas possible:
http://docs.Oracle.com/javase/tutorial/Java/generics/restrictions.html#cannotCatch

0
odoepner

Vous pouvez également utiliser un IDE prenant en charge le modèle actif (comme IntellJ IDEA par exemple ) et attribuer un raccourci tel que ee -> [tab] qui insère le try/catch/ignore pour corriger un. 

comme ceci http://img80.imageshack.us/img80/433/capturadepantalla201006j.png

comme ceci http://img641.imageshack.us/img641/6733/capturadepantalla201006w.png

0
OscarRyz