Java: Verwenden der switch-Anweisung mit enum unter der Unterklasse

264

Zuerst werde ich sagen, dass ich mit Enums in C # viel besser vertraut bin und es scheint, dass Enums in Java ein ziemliches Durcheinander sind.

Wie Sie sehen können, versuche ich in meinem nächsten Beispiel, eine switch-Anweisung @ enums zu verwenden, aber ich erhalte immer eine Fehlermeldung, egal was ich tue.

Der Fehler, den ich erhalte, ist:

Das qualifizierte Falletikett SomeClass.AnotherClass.MyEnum.VALUE_Amuss durch die nicht qualifizierte Enum-Konstante ersetzt werdenVALUE_A

Die Sache ist, dass ich den Fehler ziemlich verstehe, aber ich kann nicht einfach VALUE_A schreiben, da sich die Aufzählung in einer anderen Unterklasse befindet. Gibt es eine Möglichkeit, dieses Problem zu lösen? Und warum passiert das in Java?

//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;
            }
        }
    }
}
Popokoko
quelle
Wie darrengorman kommentierte Java Enumist äußerst praktisch , wenn man den Dreh von ihnen bekommen - nicht alle ein Chaos an. Sie sind viel flexibler und praktischer als einfache Aufzählungen (lediglich ein beschrifteter ganzzahliger Wert), wie sie auf anderen Plattformen zu sehen sind. Siehe das Oracle-Tutorial . Entdecken Sie die optimierten Set/ MapImplementierungen: EnumSet& EnumMap.
Basil Bourque
1
Wenn Sie versuchen, die case-Anweisung zu qualifizieren; In gewisser Weise versuchen Sie zu sagen, dass ich verschiedene Arten von Aufzählungen (nicht nur denselben Aufzählungstyp) in einer einzigen switch-Anweisung mischen kann. Java hat es mit diesem Ansatz gestoppt, wie hier diskutiert digizol.com/2010/10/enum-case-label-switch-java-qualified.html
lkamal
Dies geschah mir beim Umgestalten (Verschieben) einer Klasse in IntelliJ 2018.2
Daniel Alder

Antworten:

569

Ändern Sie es in dieses:

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

Der Hinweis liegt im Fehler. Sie müssen keine caseBeschriftungen mit dem Aufzählungstyp qualifizieren, sondern nur dessen Wert.

Darrengorman
quelle
20
Ok, ich fühle mich so dumm :-( Sie haben vollkommen recht, ich war überzeugt, dass ich genau diese Linie ausprobiert habe und einen Fehler damit bekommen habe, also bin ich umgezogen, um den Fall zu qualifizieren, aber Ihr Vorschlag funktioniert.
Popokoko
4
Übrigens denke ich, dass Sie feststellen werden, dass Enums in Java unglaublich nützlich sind, wenn Sie sie mehr verwenden. Ich würde nicht sagen, dass sie überhaupt ein Chaos sind :)
Darrengorman
11
@milkplusvellocet, ich weiß, dass dieser Beitrag bereits alt ist, aber ich bin gespannt, warum Java die qualifizierte Fallbezeichnung in der switch-Anweisung nicht zulässt .
Jzarsuelo
3
@ cRane01 weiß es nicht genau, aber es sorgt für eine sauberere Syntax. Die Angabe des Typs in jedem Fall wäre völlig überflüssig
Darrengorman
3
@HelloGoodbye Nein. Die Variable der switch-Anweisung definiert den Typ der case-Anweisung, sodass es sich nur um eine Aufzählung handeln kann.
Sprinter
33

Java leitet automatisch den Typ der Elemente ab case, sodass die Beschriftungen nicht qualifiziert werden müssen.

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}
Kru
quelle
14
Warum muss es nicht qualifiziert sein?
Thorbjørn Ravn Andersen
11
Wenn Sie sich qualifizieren könnten, könnten Sie etwas anderes verwenden, als MyEnumdas keinen Sinn ergibt.
Kru
1
@Kru, aber ich kann etwas grammatikalisch anderes für nicht-enum-typisierte Fallausdrücke verwenden. ZB static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}statt case 7. Diese Einschränkung für Aufzählungen macht also keinen Sinn (ich kann nicht nur Primärliterale, sondern auch manuell definierte Konstanten für den ganzzahligen switchAusdruck verwenden, aber ich kann keine manuell definierten Konstanten verwenden, sondern nur Primärnamen für Aufzählungen).
Sasha
4

das sollte reichen:

//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;
            }
        }
    }
}
Woyzeck
quelle
Du hast den Tag gerettet!
Soham Mehta
3

Falsch:

case AnotherClass.MyEnum.VALUE_A

Recht:

case VALUE_A:
Akash Yellappa
quelle
1
Ich habe Ihre positiv bewertet, weil klarer ist, worum es geht.
Joaorodr84
2

So benutze ich es. Und es funktioniert fantastisch -

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

Und das switch-casewie unten gezeigt

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

Schreiben Sie folgendermaßen someMethod():

public void someMethod() {

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

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

In der switch-Anweisung dürfen Sie nur den Konstantennamen verwenden.

dash1e
quelle