2015-07-03 8 views
5

Ho una domanda utilizzando un Enum all'interno di un'istruzione switch in Java:interruttore Java su un enum non rilevare che tutti i casi sono coperti

dichiaro un Enum in Java e utilizzare una variabile di quel tipo in uno switch dichiarazione, dove sono coperti tutti i possibili casi per i valori enumerati. Nell'esempio ogni caso inizializza una variabile che non è stato inizializzato prima del passaggio, ma il compilatore mi dà ancora un errore perché javac non riconosce che tutti i casi possibili sono coperti:

public class EnumSwitchTest { 

    public enum MyEnum { 
     FOO, 
     BAR 
    } 

    public static void main(String[] args) { 
     test(MyEnum.FOO); 
     test(MyEnum.BAR); 
    } 

    private static void test(MyEnum e) { 
     String msg; 
     switch (e) { 
      case FOO: 
       msg = "foo"; 
       break; 
      case BAR: 
       msg = "bar"; 
       break; 
     } 
     // Why does the compiler think it is possible to reach here 
     // and msg could still be uninitialized? 
     System.out.println("Enum is: " + e + " msg is: " + msg); 
    } 
} 

Perché il compilatore non in grado di rilevando che questo interruttore inizializzerà sempre msg (o genererà NullPointerException perché e è null)?

Quello che mi piacerebbe ottenere è un'istruzione switch, che gestisce tutti i casi ma genera un errore di compilazione se la classe Enum viene estesa in futuro ma non viene aggiunto alcun nuovo caso allo switch.

+1

È possibile creare nuove istanze di enum utilizzando un po 'di riflessione witchery. – immibis

+0

@immibis Anche se fosse possibile, il compilatore non dovrebbe necessariamente preoccuparsene. – biziclop

+2

La maggior parte dei compilatori è in grado di rilevare ciò, tuttavia la specifica del linguaggio Java non consente loro di interrompere la compilazione. Invece solo [raccomanda] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11) un avvertimento sui casi di switch mancanti per i valori enum. –

risposta

10

Immaginate se MyEnum fosse una classe separata. Quindi sarebbe possibile ricompilare la classe MyEnum e aggiungere nuovi valori, senza ricompilare EnumSwitchTest (quindi non ottenere alcun errore).

Quindi è possibile che un'altra classe chiami test con il nuovo valore.

0

Non conosco una soluzione che funziona con un'istruzione switch, ma è possibile utilizzare lo Enum Mapper project che fornisce un processore di annotazione che assicurerà in fase di compilazione che tutte le costanti enum siano gestite. Immagino che questo dia lo stesso risultato che stai chiedendo.

Inoltre supporta la ricerca inversa e i mapper paritial.

Problemi correlati