2010-08-22 4 views
10

Comment puis-je lancer une exception d'un constructeur enum? par exemple:Comment lancer une exception d'un constructeur enum?

public enum RLoader { 
    INSTANCE; 
    private RLoader() throws IOException { 
    .... 
    } 
} 

produit l'erreur

Unhandled type d'exception IOException

+6

Pourquoi voudriez-vous faire cela? Pour moi, cela ressemble à un abus du concept enum. Les valeurs enum sont supposées être des constantes, dont la création ne dépend de rien. Même si techniquement vous pouvez le faire (en jetant une exception non cochée au lieu d'une cochée), je vous suggère de réviser votre design. Si vous essayez d'implémenter un singleton via cette énumération, il est préférable de l'implémenter manuellement comme une classe normale. –

+2

Je suis en train de mettre en place un Singleton, mais comment l'appliquer à la main en tant que classe normale serait-il préférable? Je devrais toujours lancer une exception du code appelé par un initialiseur statique. Vous pouvez lancer des exceptions non contrôlées à partir d'un constructeur enum. – tukushan

+0

Il y a quelque chose * icky * à propos de l'obtention d'une exception simplement en accédant à une valeur enum. Pas si mal quand il s'agit d'une méthode singleton getInstance(). –

Répondre

15

Parce que les instances sont créées dans un initialiseur statique, jeter un ExceptionInInitializerError à la place.

+5

Bien que ce soit une solution possible, je ne pense pas qu'il serait logique de résoudre le problème de cette façon. –

0

Ce scénario ne peut pas fonctionner.

Vous essayez de lancer un Exception vérifié à partir du constructeur.

Ce constructeur est appelé par la déclaration d'entrée enum INSTANCE, de sorte que l'exception vérifiée ne peut pas être gérée correctement.

De même, il est à mon avis mauvais de lancer des exceptions depuis un constructeur, car un constructeur ne devrait normalement pas faire de travail et surtout ne pas créer d'erreurs.

Aussi si vous voulez lancer un IOException je suppose que vous voulez initialiser quelque chose d'un fichier, donc vous devriez peut-être considérer cet article sur dynamic enums.

+3

Si c'est un mauvais style de lancer des exceptions d'un constructeur, que faites-vous quand l'un des arguments de votre constructeur est invalide et empêchera votre classe de fonctionner? Je préfère échouer rapidement en lançant une exception afin que je puisse obtenir une trace de pile significative.Cela étant dit, je suis d'accord avec vous que le PO ne devrait pas essayer de lancer une exception dans un constructeur ** enum **. –

+0

@Kirk Woll: Je préfère utiliser des méthodes d'usine qui garantissent la validité des paramètres. Aussi, je me concentrais principalement sur les exceptions vérifiées, RuntimeException serait un meilleur moyen de signaler une erreur de vérification IMO. –

+2

Utilisation exclusive des méthodes d'usine pour toutes les instanciations d'objets? Oh le pauvre woebegotten ** nouveau ** opérateur. :) –

3

J'ai un cas où je veux utiliser enums comme touches dans certaines classes de paramètres. La base de données va stocker une valeur de chaîne, nous permettant de changer les constantes enum sans avoir à modifier la base de données (un peu moche, je sais). Je voulais lancer une exception d'exécution dans le constructeur de l'enum comme un moyen de contrôler la longueur de l'argument de chaîne pour éviter de frapper la base de données et ensuite obtenir une violation de contrainte quand je pourrais facilement le détecter moi-même.

public enum GlobalSettingKey { 
    EXAMPLE("example"); 

    private String value; 

    private GlobalSettingKey(String value) { 
     if (value.length() > 200) { 
      throw new IllegalArgumentException("you can't do that"); 
     } 
     this.value = value; 
    } 

    @Override 
    public String toString() { 
     return value; 
    } 
} 

Lorsque j'ai créé un test rapide pour cela, je trouve que l'exception jetée était pas la mienne, mais était un ExceptionInInitializerError. Peut-être que c'est stupide, mais je pense que c'est un scénario assez valable pour vouloir lancer une exception dans un initialiseur statique.

+2

Mais l'exception originale est chaînée avec ExceptionInInitializerError, donc si vous appelez 'getCause()', vous obtiendrez l'exception originale. – shrini1000

Questions connexes