2010-04-18 5 views
37

Warum wird der folgende Code nicht kompiliert, während die Case-Anweisung zuWarum bekomme ich eine Enum-Konstante Referenz kann nicht in einem Fall Label qualifiziert werden?

Wechsel
case ENUM1: doSomeStuff(); 

funktioniert?

public enum EnumType 
{ 
    ENUM1, ENUM2, ENUM3; 

    void doSomeStuff() 
    { 
     switch(this) 
     { 
     case EnumType.ENUM1: doSomeStuff(); 
     } 
    } 
} 
+4

Would „java hat Mängel und versuche nicht wirklich, dieses zu verstehen "sei eine vernünftige Antwort? Ich meine, die Antworten hier sind großartig und detailliert, aber in diesem Fall denke ich, dass es nicht wirklich wichtig ist. +1 Frage, -1 JAVA ... –

+1

@ColinD hat [die korrekte Erklärung] (http://stackoverflow.com/a/2664040/506879) von Ihrem Fall. Um ein wenig im Detail die Lösung für dieses Qualifier Thema auf Enums (mit funktionierenden Beispiel) zu sehen, lesen Sie bitte [diesen Beitrag] (http://www.davestone.net/blog/post/The-enum-constant-reference-cannot -be-qualified-in-a-case-label.aspx) – rekaszeru

Antwort

33

Dies ist die Fähigkeit, zu vergleichen, um gegen verschiedene Aufzählungstypen zu vermeiden. Es ist sinnvoll, es auf einen Typ zu beschränken, d. H. Den Typ des Enum-Werts in der switch-Anweisung.

Update: Es ist eigentlich binäre Kompatibilität zu halten. Hier ist eine von etwa auf halber Strecke chapter 13.4.9 von JLS zu zitieren:

Ein Grund für die Forderung inlining von Konstanten ist, dass switch Aussagen erfordern Konstanten auf jeder case, und keine zwei solche konstante Werte können gleich sein. Der Compiler sucht zur Kompilierungszeit in einer switch Anweisung nach doppelten Konstantenwerten. Das class Dateiformat führt keine symbolische Verknüpfung von Groß- und Kleinschreibung durch.

Mit anderen Worten, da der Klassenkennung in EnumType.ENUM1, kann sie nicht als compiletime konstanten Ausdruck dargestellt werden, während sie von der switch Anweisung erforderlich ist.

+2

Hmm ... ich bin nicht 100% überzeugt. Zu 'OtherEnumType.ENUM1' gibt der (Eclipse) -Compiler' Type mismatch: kann nicht von OtherEnumType in EnumType' konvertieren, während zu 'EnumType.ENUM1' es' 'gibt Die qualifizierte Case-Bezeichnung EnumType.ENUM1 muss durch die unqualifizierte Enum-Konstante ENUM1 ersetzt werden '. Für mich scheint es also, dass das Verbot des Typqualifikators nicht mit der Erkennung von Typkonflikten zusammenhängt. –

+1

Ich mag es! Netter Fund. – maleki

+2

Diese Antwort erklärt es nicht ausreichend. Es sollte eine Erklärung geben, wie es neu geschrieben werden sollte. – Lisa

20

Da Sie ein Objekt vom Typ EnumType einschalten und die einzigen möglichen Werte dafür die Enum-Konstanten sind, müssen Sie diese Konstanten nicht erneut innerhalb des Schalters qualifizieren. Schließlich wäre es illegal, case OtherEnumType.ENUM1: drin zu haben.

+0

Ich denke, das könnte genau der Fall sein. Wenn Sie versuchen, eine Enumeration von OtherEnumType zu verwenden, indem Sie "case enum:" anstelle von "case OtherEnumType.enum" verwenden, ergibt sich ein Fehler, der dem ähnelt, was Sie beschrieben haben. – maleki

26

Dies ist nicht wirklich Ihre Frage zu beantworten, aber wenn Sie Code auf dem ENUM-Wert je haben, können Sie auch eine abstrakte Methode in Ihren Enum erstellen, die für jeden Wert überlastet werden:

public enum EnumType { 
    ENUM1 { 
     @Override 
     public void doSomeStuff() { 
      // do something 
     } 
    }, 
    ENUM2 { 
     @Override 
     public void doSomeStuff() { 
      // do something else 
     } 
    }; 

    public abstract void doSomeStuff(); 
} 
+0

Beste Antwort +1. Diese Technik bietet eine höhere Sicherheit beim Hinzufügen neuer Werte, da Sie nicht vergessen können, die Methodenimplementierung im Vergleich zur fehlenden Fallanweisung hinzuzufügen. – whiskeysierra

+0

Hinweis: Sie müssen doSomeStuff abstract nicht erstellen, wenn Sie eine sinnvolle Standardimplementierung bereitstellen können. – whiskeysierra

+1

Wenn Sie einen aussagekräftigen Standardfall haben, legen Sie diesen als Standardfall in Ihren Switch ein. –

Verwandte Themen