Java: usando a instrução switch com enum na subclasse


265

Primeiro, afirmo que estou muito mais familiarizado com enumerações em C # e parece que enumerações em java são uma bagunça.

Como você pode ver, estou tentando usar uma instrução switch @ enums no meu próximo exemplo, mas sempre recebo um erro, não importa o que esteja fazendo.

O erro que recebo é:

O rótulo da caixa qualificado SomeClass.AnotherClass.MyEnum.VALUE_Adeve ser substituído pela constante enum não qualificadaVALUE_A

O problema é que compreendi bem o erro, mas não posso simplesmente escrever o VALUE_A, pois o enum está localizado em outra subclasse. Existe alguma maneira de resolver este problema? E por que isso está acontecendo em 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;
            }
        }
    }
}

Como comentou darrengorman, o Java Enumé extremamente útil quando você pega o jeito - não é uma bagunça. Eles são muito mais flexíveis e práticos do que enums simples (apenas um valor inteiro rotulado), como visto em outras plataformas. Veja o Tutorial do Oracle . Descubra as otimizadas Set/ Mapimplementações: EnumSet& EnumMap.
Basil Bourque

1
Quando você tenta qualificar a declaração do caso; de certa forma, você está tentando dizer que posso misturar diferentes tipos de enumerações (não apenas o mesmo tipo de enumeração) em uma única instrução switch. Java parou com esta abordagem como discutido aqui digizol.com/2010/10/enum-case-label-switch-java-qualified.html
lkamal

Isso aconteceu comigo enquanto refatoração (em movimento) uma classe em IntelliJ 2.018,2
Daniel Alder

Respostas:


570

Altere para este:

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

A pista está no erro. Você não precisa qualificar caserótulos com o tipo de enumeração, apenas seu valor.


20
Ok eu me sinto tão estúpida :-( Você está totalmente certo, eu estava convencido de que eu tentei esta linha exata e tenho um erro com que então me mudei para qualificar caso, mas sua sugestão não funciona.
Popokoko

4
Pela maneira que eu acho que você vai achar que enums em Java são extremamente úteis quando você começar a usá-los mais, eu não diria que eles são uma bagunça em todos os :)
darrengorman

11
@milkplusvellocet, eu sei que este post já é antigo, mas estou curioso para saber por que o Java não permite o rótulo de caso qualificado na instrução switch?
jzarsuelo

3
@ cRane01 não tenho certeza, mas cria uma sintaxe mais limpa. Especificando o tipo de cada caso seria totalmente redundante
darrengorman

3
@HelloGoodbye No. A variável da instrução switch define o tipo da instrução case para que ela possa ser apenas uma enumeração.
Sprinter

33

Java deduz automaticamente o tipo dos elementos case, portanto, os rótulos devem ser desqualificados.

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}

14
Por que deve ser desqualificado?
Thorbjørn Ravn Andersen

11
Se você pudesse se qualificar, poderá usar outra coisa MyEnumque não faria sentido.
Kru

1
@ Kru, mas eu posso usar algo gramaticalmente, caso contrário, para expressões de caso não enumeradas . Por exemplo, em static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}vez de case 7. Portanto, essa restrição para enumerações não faz sentido (eu posso usar não apenas literais primários, mas também constantes definidas manualmente para switchexpressão inteira , mas não posso usar constantes definidas manualmente, mas apenas nomes primários para enumerações).
Sasha

4

isto deve fazer:

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

Você salvou o dia!
Soham Mehta


2

É assim que eu estou usando. E está funcionando de maneira fantástica -

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

E o switch-casecomo mostrado abaixo

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

0

Escreva someMethod()desta maneira:

public void someMethod() {

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

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

Na instrução switch, você deve usar apenas o nome da constante.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.