Java: użycie instrukcji switch z enum w podklasie

265

Najpierw stwierdzę, że znacznie lepiej znam wyliczenia w języku C # i wygląda na to, że wyliczenia w języku Java są dość nieporządne.

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

Błąd, który otrzymuję to:

Etykietę kwalifikowanego przypadku SomeClass.AnotherClass.MyEnum.VALUE_Anależy zastąpić niekwalifikowaną stałą wyliczaniaVALUE_A

Chodzi o to, że całkiem rozumiem błąd, ale nie mogę po prostu napisać WARTOŚCI_A, ponieważ wyliczenie znajduje się w innej podklasie. Czy istnieje sposób na rozwiązanie tego problemu? I dlaczego tak się dzieje 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;
            }
        }
    }
}
Popokoko
źródło
Jak skomentował darrengorman, Java Enumjest bardzo przydatna, gdy się ich zrozumie - wcale nie jest bałagan. Są one znacznie bardziej elastyczne i praktyczne niż proste wyliczenia (tylko wartość oznaczona liczbą całkowitą), jak widać na innych platformach. Zobacz samouczek Oracle . Odkryj zoptymalizowane Set/ Mapwdrożenia: EnumSeti EnumMap.
Basil Bourque,
1
Gdy próbujesz zakwalifikować opis przypadku; w pewnym sensie próbujesz powiedzieć, że mogę mieszać różne typy wyliczeń (nie tylko ten sam typ wyliczeń) w ramach jednej instrukcji switch. Java zatrzymała to dzięki temu podejściu, jak omówiono tutaj digizol.com/2010/10/enum-case-label-switch-java-qualified.html
lkamal
Zdarzyło mi się to podczas refaktoryzacji (przeprowadzki) klasy w IntelliJ 2018.2
Daniel Alder

Odpowiedzi:

570

Zmień to na:

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

Wskazówka tkwi w błędzie. Nie musisz kwalifikować caseetykiet typu wyliczeniowego, tylko jego wartość.

darrengorman
źródło
20
Ok, czuję się tak głupio :-( Masz całkowitą rację, byłem przekonany, że wypróbowałem tę dokładną linię i dostałem błąd, więc przeniosłem się, aby zakwalifikować sprawę, ale twoja sugestia
DZIAŁA
4
Nawiasem mówiąc, myślę, że przekonasz się, że wyliczenia w Javie są niezwykle przydatne, gdy zaczniesz ich więcej używać, nie powiedziałbym, że są w ogóle bałaganem :)
darrengorman
11
@milkplusvellocet, wiem, że ten post jest już stary, ale jestem ciekawy, dlaczego Java nie zezwala na etykietę kwalifikowanej sprawy w instrukcji switch?
jzarsuelo,
3
@ cRane01 nie wiem na pewno, ale zapewnia czystszą składnię. Określenie rodzaju w każdym przypadku byłoby całkowicie zbędne
darrengorman,
3
@HelloGoodbye Nie. Zmienna instrukcji switch określa typ instrukcji case, więc może być tylko jednym wyliczeniem.
sprinter
33

Java automatycznie określa typ elementów case, więc etykiety muszą być niekwalifikowane.

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}
Kru
źródło
14
Dlaczego musi to być niekwalifikowane?
Thorbjørn Ravn Andersen
11
Jeśli możesz się zakwalifikować, możesz użyć czegoś innego niż to, MyEnumco nie ma sensu.
Kru,
1
@Kru, ale można użyć czegoś innego-gramatycznie dla non-enum wpisany przypadku wyrażeń. Np. static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}Zamiast case 7. To ograniczenie dla wyliczeń nie ma sensu (mogę używać nie tylko podstawowych literałów, ale także ręcznie zdefiniowanych stałych dla switchwyrażenia liczb całkowitych , ale nie mogę używać ręcznie zdefiniowanych stałych, ale tylko podstawowych nazw dla wyliczeń).
Sasha
4

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;
            }
        }
    }
}
Woyzeck
źródło
Uratowałeś dzień!
Soham Mehta
3

Źle:

case AnotherClass.MyEnum.VALUE_A

Dobrze:

case VALUE_A:
Akash Yellappa
źródło
1
Głosowałem za tobą, ponieważ jest jasne, o co chodzi.
joaorodr84
2

Tak to wykorzystuję. 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;
        }
    }

I switch-casejak 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;
        }
    }
}
Jimit Patel
źródło
0

Napisz 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 musisz używać tylko stałej nazwy.

dash1e
źródło