2015-07-03 4 views
5

ich eine Frage mit einem Enum innerhalb einer switch-Anweisung in Java haben:Java-Schalter über einen ENUM nicht erkennt, dass alle Fälle abgedeckt sind

ich eine Enum in Java deklarieren und eine Variable dieses Typs in einem Schalter verwenden Anweisung, in der alle möglichen Fälle für enum-Werte behandelt werden. Im Beispiel initialisiert jeder Fall eine Variable, die nicht vor dem Schalter initialisiert wurde, aber der Compiler gibt mir noch einen Fehler, da javac nicht erkennt, dass alle möglichen Fälle abgedeckt sind:

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

Warum ist der Compiler nicht in der Lage Erkennen, dass dieser Schalter immer msg initialisieren wird (oder eine NullPointerException werfen, weil enull ist)?

Was ich erreichen möchte, ist eine switch-Anweisung, die alle Fälle behandelt, aber zu einem Kompilierungsfehler führt, wenn die Enum-Klasse in der Zukunft erweitert wird, aber kein neuer Fall zum Switch hinzugefügt wird.

+1

Es ist möglich, neue Instanzen eines Enums mit Reflection Witchery zu erstellen. – immibis

+0

@immibis Selbst wenn es möglich wäre, sollte der Compiler nicht unbedingt darüber nachdenken. – biziclop

+2

Die meisten Compiler können dies erkennen, aber die Java-Sprachspezifikation erlaubt ihnen nicht, die Kompilierung abzubrechen. Stattdessen gibt es nur [empfiehlt] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11) eine Warnung über fehlende Switch Cases für Enum-Werte. –

Antwort

10

Stellen Sie sich vor, wenn MyEnum eine separate Klasse ist. Dann wäre es möglich, die MyEnum-Klasse neu zu kompilieren und neue Werte hinzuzufügen, ohne EnumSwitchTest neu zu kompilieren (so dass keine Fehler auftreten).

Dann wäre es für eine andere Klasse möglich, test mit dem neuen Wert aufzurufen.

0

Ich kenne keine Lösung, die mit einer switch-Anweisung funktioniert, aber Sie können die Enum Mapper project verwenden, die einen Annotationsprozessor bereitstellt, der bei der Kompilierung sicherstellen wird, dass alle enum-Konstanten behandelt werden. Ich denke, das ergibt das gleiche Ergebnis, nach dem Sie fragen.

Darüber hinaus unterstützt Reverse Lookup und Parititial Mapper.

Verwandte Themen