2010-08-22 11 views
10

Come posso generare un'eccezione da un costruttore enum? es:Come lanciare un'eccezione da un costruttore enum?

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

produce l'errore

tipo di eccezione non gestita IOException

+6

Perché vuoi farlo? Per me questo sembra un abuso del concetto di enum. I valori Enum dovrebbero essere costanti, la cui creazione non dipende da nulla. Anche se tecnicamente lo si potrebbe fare (lanciando un'eccezione non controllata invece di una selezionata), ti suggerirei di rivedere il tuo design. Se stai cercando di implementare un Singleton tramite questo enum, è meglio implementarlo a mano come una classe normale. –

+2

Sto implementando un Singleton, ma come potrebbe essere implementato a mano come una classe normale essere meglio? Dovrei comunque lanciare un'eccezione dal codice chiamato da un inizializzatore statico. È possibile eseguire eccezioni non controllate da un costruttore enum. – tukushan

+0

c'è qualcosa * icky * nell'ottenere un'eccezione generata semplicemente accedendo a un valore enum. Non così male quando si tratta di un metodo getInstance() singleton. –

risposta

15

Poiché le istanze vengono create in un inizializzatore statico, lanciare un ExceptionInInitializerError invece.

+5

Anche se questa è una possibile soluzione, non penso che avrebbe senso risolvere il problema in questo modo. –

0

Tale scenario non può funzionare.

Si sta provando a lanciare un controllo Exception dal costruttore.

Questo costruttore viene chiamato dalla dichiarazione di immissione enum INSTANCE, pertanto l'eccezione verificata non può essere gestita correttamente.

Inoltre è a mio parere che è uno stile sbagliato lanciare eccezioni da un costruttore, in quanto un costruttore normalmente non dovrebbe fare alcun lavoro e soprattutto non creare errori.

Inoltre se si vuole buttare un IOException Presumo che si desidera inizializzare qualcosa da un file, così si dovrebbe forse prendere in considerazione questo articolo sul dynamic enums.

+3

Se è uno stile sbagliato lanciare eccezioni da un costruttore, cosa si fa quando uno degli argomenti del costruttore non è valido e impedisce alla classe di funzionare? Preferisco fallire velocemente lanciando un'eccezione in modo da ottenere una traccia di stack significativa.Detto questo, sono d'accordo con te sul fatto che l'OP non dovrebbe tentare di lanciare un'eccezione nel costruttore di ** enum **. –

+0

@ Kirk Woll: preferisco usare metodi di fabbrica che garantiscano la validità dei parametri. Inoltre mi sono concentrato principalmente su Eccezioni controllate, RuntimeException sarebbe un modo migliore per segnalare un errore di verifica IMO. –

+2

Uso esclusivo di metodi di fabbrica per l'istanziazione di tutti gli oggetti? Oh il povero woebegotten ** nuovo ** operatore. :) –

3

Ho un caso in cui desidero utilizzare le enumerazioni come chiavi in ​​alcune classi di impostazioni. Il database memorizzerà un valore stringa, permettendoci di cambiare le costanti enum senza dover udpare il database (un po 'brutto, lo so). Volevo lanciare un'eccezione di runtime nel costruttore di enum come modo per controllare la lunghezza dell'argomento della stringa per evitare di colpire il database e quindi ottenere una violazione del vincolo quando potevo facilmente rilevarlo da solo.

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; 
    } 
} 

Quando ho creato un test rapido per questo, ho trovato che l'eccezione generata non era mio, ma invece era un ExceptionInInitializerError.

Forse questo è stupido, ma penso che sia uno scenario abbastanza valido per voler generare un'eccezione in un inizializzatore statico.

+2

Ma l'eccezione originale è concatenata con ExceptionInInitializerError, quindi se si chiama 'getCause()' su di essa, si otterrà l'eccezione originale. – shrini1000

Problemi correlati