Java: utilisation de l'instruction switch avec enum sous la sous-classe

265

Tout d'abord, je dirai que je suis beaucoup plus familier avec les énumérations en C # et il semble que les énumérations en java soient un vrai gâchis.

Comme vous pouvez le voir, j'essaie d'utiliser une instruction switch @ enums dans mon exemple suivant, mais j'obtiens toujours une erreur, quoi que je fasse.

L'erreur que je reçois est:

L'étiquette de boîtier qualifiée SomeClass.AnotherClass.MyEnum.VALUE_Adoit être remplacée par la constante d'énumération non qualifiéeVALUE_A

Le fait est que je comprends bien l'erreur, mais je ne peux pas simplement écrire VALUE_A car l'énumération est située dans une autre sous-classe. Existe-t-il un moyen de résoudre ce problème? Et pourquoi cela se passe-t-il en 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
la source
Comme l'a commenté Darrengorman, Java Enumest extrêmement pratique une fois que vous les maîtrisez - pas du tout un gâchis. Ils sont beaucoup plus flexibles et pratiques que les énumérations simples (simplement une valeur entière étiquetée) comme on le voit sur d'autres plates-formes. Voir le didacticiel Oracle . Découvrez les optimisations Set/ Mapimplémentations: EnumSet& EnumMap.
Basil Bourque
1
Lorsque vous essayez de qualifier l'énoncé de cas; d'une certaine manière, vous essayez de dire que je peux mélanger différents types d'énumérations (pas seulement le même type d'énumération) au sein d'une même instruction switch. Java l'a arrêtée avec cette approche comme discuté ici digizol.com/2010/10/enum-case-label-switch-java-qualified.html
lkamal
Cela m'est arrivé en refactorisant (déplaçant) une classe dans IntelliJ 2018.2
Daniel Alder

Réponses:

570

Changez-le en ceci:

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

L'indice est dans l'erreur. Vous n'avez pas besoin de qualifier les caseétiquettes avec le type enum, juste sa valeur.

darrengorman
la source
20
Ok, je me sens tellement stupide :-( Vous avez tout à fait raison, j'étais convaincu d'avoir essayé cette ligne exacte et j'ai eu une erreur avec cela, alors j'ai déménagé pour qualifier le cas, mais votre suggestion fonctionne.
Popokoko
4
Au fait, je pense que vous constaterez que les énumérations en Java sont incroyablement utiles une fois que vous commencez à les utiliser davantage, je ne dirais pas qu'elles sont un gâchis du tout :)
darrengorman
11
@milkplusvellocet, je sais que ce message est déjà ancien, mais je suis curieux de savoir pourquoi Java n'autorise pas le libellé de cas qualifié dans l'instruction switch?
jzarsuelo
3
@ cRane01 ne sait pas avec certitude, mais cela permet une syntaxe plus propre. Spécifier le type sur chaque cas serait totalement redondant
darrengorman
3
@HelloGoodbye No. La variable de l'instruction switch définit le type de l'instruction case afin qu'elle ne puisse être qu'une énumération.
sprinter
33

Java déduit automatiquement le type des éléments case, de sorte que les étiquettes doivent être non qualifiées.

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}
Kru
la source
14
Pourquoi doit- il être sans réserve?
Thorbjørn Ravn Andersen
11
Si vous pouviez vous qualifier, alors vous pourriez utiliser autre chose que MyEnumce qui n'aurait pas de sens.
Kru
1
@Kru, mais je peux utiliser quelque chose grammaticalement - sinon pour les expressions de casse non typées enum. Par exemple static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}au lieu de case 7. Cette restriction pour les énumérations n'a donc aucun sens (je peux utiliser non seulement des littéraux primaires, mais aussi des constantes définies manuellement pour l' switchexpression entière , mais je ne peux pas utiliser des constantes définies manuellement, mais uniquement des noms primaires pour les énumérations).
Sasha
4

cela devrait faire:

//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
la source
Vous avez sauvé la journée!
Soham Mehta
3

Faux:

case AnotherClass.MyEnum.VALUE_A

Droite:

case VALUE_A:
Akash Yellappa
la source
1
J'ai voté pour le vôtre car il est plus clair sur le problème.
joaorodr84 du
2

Voilà comment je l'utilise. Et cela fonctionne à merveille -

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

Et switch-casecomme indiqué ci-dessous

@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
la source
0

Écrivez someMethod()de cette façon:

public void someMethod() {

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

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

Dans l'instruction switch, vous devez utiliser uniquement le nom constant.

dash1e
la source