Java: uso de la instrucción switch con enum en la subclase

265

Primero declararé que estoy mucho más familiarizado con las enumeraciones en C # y parece que las enumeraciones en Java son un desastre.

Como puede ver, estoy tratando de usar una instrucción switch @ enums en mi próximo ejemplo, pero siempre recibo un error sin importar lo que esté haciendo.

El error que recibo es:

La etiqueta de caso calificada SomeClass.AnotherClass.MyEnum.VALUE_Adebe ser reemplazada por la constante enum no calificadaVALUE_A

La cuestión es que entiendo bastante el error, pero no puedo escribir el VALOR_A ya que la enumeración se encuentra en otra subclase. ¿Hay alguna manera de resolver este problema? ¿Y por qué está sucediendo 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
fuente
Como comentó Darrengorman, Java Enumes extremadamente útil una vez que los dominas, en absoluto un desastre. Son mucho más flexibles y prácticos que las enumeraciones simples (simplemente un valor entero etiquetado) como se ve en otras plataformas. Vea el Tutorial de Oracle . Descubra el optimizado Set/ Mapimplementaciones: EnumSet& EnumMap.
Basil Bourque
1
Cuando intenta calificar la declaración del caso; en cierto modo, está tratando de decir que puedo mezclar diferentes tipos de enumeraciones (no solo el mismo tipo de enumeración) dentro de una sola instrucción de cambio. Java lo ha detenido con este enfoque como se discute aquí digizol.com/2010/10/enum-case-label-switch-java-qualified.html
lkamal
Esto me sucedió mientras refactorizaba (movía) una clase en IntelliJ 2018.2
Daniel Alder

Respuestas:

570

Cámbialo a esto:

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

La pista está en el error. No necesita calificar las caseetiquetas con el tipo de enumeración, solo su valor.

darrengorman
fuente
20
Ok, me siento tan estúpido :-( Tienes toda la razón, estaba convencido de que probé esta línea exacta y obtuve un error con eso, así que me mudé para calificar el caso, pero su sugerencia NO funciona.
Popokoko
44
Por cierto creo que usted encontrará que las enumeraciones en Java son muy útiles una vez que comience a usarlos más, yo no diría que son un desastre en absoluto :)
darrengorman
11
@milkplusvellocet, sé que esta publicación ya es antigua, pero tengo curiosidad por qué Java no permite la etiqueta de caso calificado en la declaración de cambio.
jzarsuelo
3
@ cRane01 no lo sé con certeza, pero hace una sintaxis más limpia. Especificar el tipo en cada caso sería totalmente redundante
darrengorman
3
@HelloGoodbye No. La variable de la declaración de cambio define el tipo de declaración de caso, por lo que solo puede ser una enumeración.
velocista
33

Java infiere automáticamente el tipo de elementos case, por lo que las etiquetas no deben estar calificadas.

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}
Kru
fuente
14
¿Por qué debe ser no calificado?
Thorbjørn Ravn Andersen
11
Si pudiera calificar, entonces podría usar algo más MyEnumque no tendría sentido.
Kru
1
@Kru, pero puedo usar algo gramaticalmente más para expresiones de caso sin tipo de enumeración. Por ejemplo, en static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}lugar de case 7. Entonces, esta restricción para las enumeraciones no tiene sentido (puedo usar no solo literales primarios, sino también constantes definidas manualmente para la switchexpresión entera , pero no puedo usar constantes definidas manualmente, sino solo nombres primarios para las enumeraciones).
Sasha
4

esto debería hacer:

//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
fuente
¡Salvaste el día!
Soham Mehta
3

Incorrecto:

case AnotherClass.MyEnum.VALUE_A

Correcto:

case VALUE_A:
Akash Yellappa
fuente
1
Elegí el tuyo porque es más claro cuál es el problema.
joaorodr84
2

Así es como lo estoy usando. Y está funcionando fantásticamente.

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

Y el switch-caseque se muestra a continuación

@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
fuente
0

Escribe someMethod()de esta manera:

public void someMethod() {

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

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

En la instrucción switch, debe usar solo el nombre constante.

dash1e
fuente