Java: использование оператора switch с enum в подклассе

265

Во-первых, я скажу, что я гораздо лучше знаком с перечислениями в C #, и кажется, что перечисления в Java - довольно беспорядок.

Как вы можете видеть, я пытаюсь использовать оператор switch @ enums в моем следующем примере, но я всегда получаю ошибку, независимо от того, что я делаю.

Я получаю ошибку:

Квалифицированная метка регистра SomeClass.AnotherClass.MyEnum.VALUE_Aдолжна быть заменена неквалифицированной константой enumVALUE_A

Дело в том , я совсем понимаю ошибку , но я не могу просто написать VALUE_A , так как перечисление находится в другом подклассе. Есть ли способ решить эту проблему? И почему это происходит на 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
источник
Как darrengorman прокомментировал Java Enumявляются чрезвычайно удобно , как только вы получите повесить их - вовсе не беспорядок. Они гораздо более гибкие и практичные, чем простые перечисления (просто помеченные целочисленные значения), как это видно на других платформах. Смотрите руководство по Oracle . Откройте для себя оптимизированные Set/ Mapреализации: EnumSet& EnumMap.
Василий Бурк
1
Когда вы пытаетесь квалифицировать заявление дела; В некотором смысле, вы пытаетесь сказать, что я могу смешивать различные типы перечислений (не просто один и тот же тип перечисления) в пределах одного оператора switch. Java остановила его с помощью этого подхода, как обсуждалось здесь digizol.com/2010/10/enum-case-label-switch-java-qualified.html
lkamal
Это случилось со мной во время рефакторинга (перемещения) класса в IntelliJ 2018.2
Даниэль Олдер

Ответы:

570

Измените это на это:

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

Подсказка в ошибке. Вам не нужно квалифицировать caseметки с типом enum, только его значение.

darrengorman
источник
20
Хорошо, я чувствую себя настолько глупо :-( Вы совершенно правы, я был убежден, что попробовал эту точную линию и получил ошибку с этим, поэтому я перешел к квалификации случая, но ваше предложение работает.
Попококо
4
Кстати, я думаю, вы обнаружите, что перечисления в Java невероятно полезны, как только вы начнете их больше использовать, я бы не сказал, что они вообще беспорядок :)
darrengorman
11
@milkplusvellocet, я знаю, что этот пост уже устарел, но мне любопытно, почему Java не разрешает использовать метку прецедента в выражении switch?
jzarsuelo
3
@ cRane01 точно не знаю, но это делает синтаксис более понятным. Указание типа в каждом случае было бы совершенно излишним
darrengorman
3
@HelloGoodbye Нет. Переменная оператора switch определяет тип оператора case, поэтому она может быть только одним перечислением.
спринтер
33

Java автоматически определяет тип элементов case, поэтому метки должны быть неквалифицированными.

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}
Кру
источник
14
Почему это должно быть неквалифицированным?
Турбьёрн Равн Андерсен
11
Если бы вы могли готовиться, вы могли бы использовать что-то еще, MyEnumчто не имело бы смысла.
Кру
1
@Kru, но я могу использовать что-то грамматически, иначе для не типизированных выражений падежа. Например, static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}вместо case 7. Таким образом, это ограничение для перечислений не имеет смысла (я могу использовать не только первичные литералы, но и определенные вручную константы для целочисленного switchвыражения, но я не могу использовать определяемые вручную константы, но только основные имена для перечислений).
Саша
4

это должно сделать:

//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;
            }
        }
    }
}
Войцек
источник
Вы спасли день!
Сохам Мехта
3

Неправильно:

case AnotherClass.MyEnum.VALUE_A

Правильно:

case VALUE_A:
Акаш Йеллаппа
источник
1
Я проголосовал за вас, потому что в этом вопросе яснее.
joaorodr84
2

Вот как я это использую. И это работает фантастически -

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

И switch-caseкак показано ниже

@Override
public void onClick(MyOrderDetailDelgate.Button button, int position) {
    switch (button) {
        case REPORT_ISSUES: {
            break;
        }
        case CANCEL_ORDER: {
            break;
        }
        case RETURN_ORDER: {
            break;
        }
    }
}
Джимит Патель
источник
0

Напишите someMethod()так:

public void someMethod() {

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

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

В операторе switch вы должны использовать только имя константы.

dash1e
источник