2015-07-03 3 views
5

Mam pytanie korzystając enum wewnątrz instrukcji switch w Java:przełącznik Java nad wyliczenia nie wykryje, że wszystkie przypadki są objęte

Oświadczam wyliczenia w Javie i użyć zmiennej tego typu w przełączniku oświadczenie, w którym uwzględniono wszystkie możliwe przypadki wartości wyliczeniowych. Na przykład każdy przypadek inicjuje zmienną, która nie została zainicjowana przed przełącznikiem, ale kompilator nadal daje mi błąd, ponieważ javac nie rozpoznaje, że wszystkie możliwe przypadki są objęte:

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

Dlaczego kompilator nie stanie wykrywanie, że ten przełącznik zawsze zainicjuje msg (lub wyrzuci wyjątek NullPointerException, ponieważ e jest null)?

Co chciałbym osiągnąć to instrukcja switch, która obsługuje wszystkie przypadki, ale spowoduje błąd kompilacji, jeśli klasa Enum zostanie rozszerzona w przyszłości, ale do przełącznika nie zostanie dodany nowy przypadek.

+1

Możliwe jest tworzenie nowych instancji wyliczenia za pomocą czarów. – immibis

+0

@immibis Nawet jeśli było to możliwe, kompilator nie powinien się tym przejmować. – biziclop

+2

Większość kompilatorów może to wykryć, jednak specyfikacja języka Java nie pozwala im przerwać kompilacji. Zamiast tego [zaleca (http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11) ostrzeżenie o brakujących przypadkach przełączania dla wartości wyliczonych. –

Odpowiedz

10

Wyobraź sobie, że MyEnum była oddzielną klasą. Wtedy będzie można ponownie skompilować klasę MyEnum i dodać nowe wartości, bez ponownej kompilacji EnumSwitchTest (nie otrzymując żadnych błędów).

Następnie inna klasa może wywołać test z nową wartością.

0

Nie znam rozwiązania, które działa z instrukcją switch, ale można użyć narzędzia Enum Mapper project, które zapewnia procesor adnotacji, który upewni się podczas kompilacji, że wszystkie stałe enum są obsługiwane. Sądzę, że daje to ten sam rezultat, o który prosisz.

Ponadto obsługuje odwrotne wyszukiwanie i odwzorowanie mapowania.

Powiązane problemy