2012-04-15 7 views
157

Najpierw stwierdzę, że jestem dużo bardziej zaznajomiony z wyliczeniami w C# i wydaje się, że wyliczenia w Java są dość nieładne.Java: używanie instrukcji switch z enum pod podklasą

Jak widać, próbuję użyć instrukcji switch @ enums w moim następnym przykładzie, ale zawsze otrzymuję błąd bez względu na to, co robię.

Błąd zgłaszany jest:

Wykwalifikowana przypadek etykieta SomeClass.AnotherClass.MyEnum.VALUE_A muszą zostać zastąpione przez niewykwalifikowanego wyliczenia stałej VALUE_A

Chodzi o to, że dość zrozumieć błąd, ale ja nie można po prostu napisać VALUE_A, ponieważ wyliczenie znajduje się w innej podklasie. Czy istnieje sposób na rozwiązanie tego problemu? I dlaczego dzieje się to w Javie?

//Main Class 
public class SomeClass { 

    //Sub-Class 
    public static class AnotherClass { 
     public enum MyEnum { 
      VALUE_A, VALUE_B 
     }  
     public MyEnum myEnum; 
    } 

    public void someMethod() { 
     MyEnum enumExample //... 

     switch (enumExample) { 
      case AnotherClass.MyEnum.VALUE_A: { <-- error on this line 
       //.. 
       break; 
      } 
     } 
    } 
} 
+0

Jak darrengorman skomentował Java [ '] (http://docs.oracle.com/javase/8/ Enum' docs/api/java/lang/Enum.html) są * niezwykle * poręczne, gdy już się ich pozbywasz - wcale nie bałagan. Są znacznie bardziej elastyczne i praktyczne niż zwykłe wyliczenia (jedynie wartość liczbowa z etykietą), jak widać na innych platformach. Zobacz [Oracle Tutorial] (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html). Odkryj zoptymalizowane implementacje 'Set' /' Map': ['EnumSet'] (http://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html) & [' EnumMap'] (http://docs.oracle.com/javase/8/docs/api/java/util/EnumMap.html). –

+0

Podczas próby zakwalifikowania instrukcji sprawy; w pewnym sensie próbujesz powiedzieć, że mogę mieszać różne typy wyliczeń (nie tylko ten sam typ wyliczeniowy) w pojedynczej instrukcji switch. Java zatrzymała to przy użyciu tego podejścia, jak to omówiono tutaj: http://www.digizol.com/2010/10/enum-case-label-switch-java-qualified.html – lkamal

Odpowiedz

362

zmienić go na to:

switch (enumExample) { 
    case VALUE_A: { 
     //.. 
     break; 
    } 
} 

Wskazówkę jest w błędzie. Nie musisz kwalifikować etykiet case z typem wyliczenia, tylko z jego wartością.

+13

OK, czuję się tak głupio :-( Masz całkowitą rację, byłam przekonana, że ​​wypróbowałam tę dokładną linię i dostałam z tym błąd, więc przeniosłam się do zakwalifikowania sprawy, ale twoja sugestia działa ... – Popokoko

+4

Tak przy okazji, myślę, że " Przekonają się, że wyliczenia w Javie są niezwykle użyteczne, gdy zacznie się ich więcej używać, nie powiedziałbym, że to w ogóle bałagan :) – darrengorman

+0

Wierzę, że znajdę się w najbliższej przyszłości :) W każdym razie, jest to zdecydowanie najlepsze forum do programowania dzięki ludziom takim jak Ty. – Popokoko

21

Java wnioskuje automatycznie typ elementów w case, więc etykiety muszą być bezwarunkowe.

int i; 
switch(i) { 
    case 5: // <- integer is expected 
} 
MyEnum e; 
switch (e) { 
    case VALUE_A: // <- an element of the enumeration is expected 
} 
+8

Dlaczego to musi być niewskazane? –

+8

Jeśli mógłbyś się zakwalifikować, możesz użyć czegoś innego niż 'MyEnum', który nie miałby sensu. – Kru

+0

@Kru, ale ja ** może ** używać czegoś gramatycznie - w przeciwnym razie do wyrażeń nie pisanych przy użyciu wyrażeń typu enum. Na przykład.'static final int MY_CONST = 7; ...; switch (intVariable) {case MY_CONST: ...;} 'zamiast' case 7'. Tak więc to ograniczenie dla enums sprawia, że ​​** nie ma sensu (mogę używać nie tylko podstawowych literałów, ale także ręcznie zdefiniowanych stałych dla całkowitego wyrażenia 'switch', ale nie mogę używać stałych zdefiniowanych ręcznie, ale tylko podstawowe nazwy dla wylicza). – Sasha

0

Zapis someMethod() w ten sposób:

public void someMethod() { 

    SomeClass.AnotherClass.MyEnum enumExample = SomeClass.AnotherClass.MyEnum.VALUE_A; 

    switch (enumExample) { 
    case VALUE_A: 
     break; 
    } 

} 

W instrukcji switch należy używać tylko stałą nazwę.

2

powinno to zrobić:

//Main Class 
public class SomeClass { 

    //Sub-Class 
    public static class AnotherClass { 
     public enum MyEnum { 
      VALUE_A, VALUE_B 
     }  
     public MyEnum myEnum; 
    } 

    public void someMethod() { 
     AnotherClass.MyEnum enumExample = AnotherClass.MyEnum.VALUE_A; //... 

     switch (enumExample) { 
      case VALUE_A: { //<-- error on this line 
      //.. 
      break; 
      } 
     } 
    } 
} 
0

ten sposób używam go. I działa fantastycznie -

public enum Button { 
     REPORT_ISSUES(0), 
     CANCEL_ORDER(1), 
     RETURN_ORDER(2); 

     private int value; 

     Button(int value) { 
      this.value = value; 
     } 

     public int getValue() { 
      return value; 
     } 
    } 

a switch-case jak pokazano poniżej

@Override 
public void onClick(MyOrderDetailDelgate.Button button, int position) { 
    switch (button) { 
     case REPORT_ISSUES: { 
      break; 
     } 
     case CANCEL_ORDER: { 
      break; 
     } 
     case RETURN_ORDER: { 
      break; 
     } 
    } 
}