Java: використання оператора переключення з перерахунком під підкласом


265

Спершу зазначу, що я набагато більше знайомий із перерахунками в C #, і здається, що перерахунки в Java - це зовсім безлад.

Як ви бачите, я намагаюсь у своєму наступному прикладі використовувати оператор переключення @ перераховує, але я завжди отримую помилку незалежно від того, що я роблю.

Я отримую помилку:

Кваліфіковану мітку регістру SomeClass.AnotherClass.MyEnum.VALUE_Aнеобхідно замінити на некваліфіковану константу перерахункуVALUE_A

Справа в тому, що я цілком розумію помилку, але я не можу просто написати VALUE_A, оскільки перерахунок знаходиться в іншому підкласі. Чи є спосіб вирішити цю проблему? І чому це відбувається на Яві?

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

Як darrengorman прокоментував Java Enumє надзвичайно зручно , як тільки ви отримаєте повісити їх - зовсім не безлад. Вони набагато гнучкіші та практичніші, ніж прості перерахунки (просто позначене цілочисельне значення), як це спостерігається на інших платформах. Дивіться навчальний посібник Oracle . Відкрийте для себе оптимізовані Set/ Mapреалізації: EnumSet& EnumMap.
Василь Бурк

1
Коли ви намагаєтеся кваліфікувати заяву справи; певним чином, ви намагаєтесь сказати, що я можу змішувати різні види перерахунків (не просто одного типу перерахунку) в межах одного оператора переключення. 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, а лише його значення.


20
Гаразд, я відчуваю себе таким дурним :-( Ви абсолютно праві, я був переконаний, що я спробував цю точну лінію і отримав помилку з цим, тому я перейшов до кваліфікаційного випадку, але ваша пропозиція працює.
Попококо

4
До речі, я думаю, що ви побачите, що перерахунки на Яві неймовірно корисні, як тільки ви почнете більше їх використовувати, я б не сказав, що вони взагалі безлад :)
darrengorman

11
@milkplusvellocet, я знаю, що цей пост уже старий, але мені цікаво, чому Java не дозволяє дозволити кваліфіковану мітку регістру в операторі перемикача?
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
Чому він повинен бути некваліфікованим?
Thorbjørn Ravn Andersen

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

Ти врятував день!
Сохам Мехта


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 потрібно використовувати лише постійне ім'я.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.