Java: usando la declaración de cambio con enumeración en la subclase

6 minutos de lectura

avatar de usuario
Popokoko

Primero, diré 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 declaración de cambio @ enumeraciones en mi próximo ejemplo, pero siempre obtengo un error sin importar lo que esté haciendo.

El error que recibo es:

La etiqueta de caso calificada SomeClass.AnotherClass.MyEnum.VALUE_A debe reemplazarse con la constante de enumeración no calificada VALUE_A

la cosa soy yo bastante entiendo el error, pero no puedo simplemente escribir VALUE_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;
            }
        }
    }
}

  • Como comentó darrengorman, Java Enum son extremadamente útil una vez que aprendes a manejarlos, no es 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. Ver el Tutorial de oráculo. Descubre el optimizado Set/Map implementaciones: EnumSet & EnumMap.

    – Basil Bourque

    5 de agosto de 2017 a las 20:12


  • 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 declaración de cambio. Java lo ha detenido con este enfoque como se explica aquí digizol.com/2010/10/enum-case-label-switch-java-qualified.html

    – lkamal

    16 de noviembre de 2017 a las 18:52


  • Esto me sucedió mientras refactorizaba (mover) una clase en IntelliJ 2018.2

    – Daniel Alder

    29 de julio de 2019 a las 8:28

Cámbialo por esto:

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

La pista está en el error. No necesitas calificar case etiquetas con el tipo de enumeración, solo su valor.

  • 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 pasé a calificar el caso, pero tu sugerencia SÍ funciona.

    – Popokoko

    15 de abril de 2012 a las 11:09

  • Por cierto, creo que encontrará que las enumeraciones en Java son increíblemente útiles una vez que comience a usarlas más, no diría que son un desastre en absoluto 🙂

    – darrengorman

    15 de abril de 2012 a las 11:17

  • @milkplusvellocet, sé que esta publicación ya es antigua, pero tengo curiosidad por qué Java no permite la etiqueta de caja calificada en la declaración de cambio?

    – jjz

    6 de diciembre de 2013 a las 17:43

  • @ cRane01 no lo sé con certeza, pero lo convierte en una sintaxis más limpia. Especificar el tipo en cada caso sería totalmente redundante

    – darrengorman

    9 de diciembre de 2013 a las 10:28

  • @HelloGoodbye No. La variable de la declaración de cambio define el tipo de declaración del caso, por lo que solo puede ser una enumeración.

    – velocista

    23 de diciembre de 2015 a las 1:49

avatar de usuario
Akash Yellapa

Equivocado:

case AnotherClass.MyEnum.VALUE_A

Derecha:

case VALUE_A:

  • Voté el tuyo porque es más claro cuál es el problema.

    – joaorodr84

    30 sep 2019 a las 22:00

Java infiere automáticamente el tipo de los elementos en casepor lo que las etiquetas deben ser no calificadas.

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

  • Por qué deber ser incompetente?

    – Thorbjorn Ravn Andersen

    19 de agosto de 2015 a las 13:25

  • Si pudiera calificar, entonces podría usar algo más que MyEnum que no tendría sentido.

    – Kru

    31 de agosto de 2015 a las 18:03

  • @Kru, pero yo pueden use algo gramaticalmente diferente para expresiones de casos sin enumeración. P.ej static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;} en vez de case 7. Así que esta restricción para las enumeraciones hace no sentido (puedo usar no solo literales primarios, sino también constantes definidas manualmente para números enteros). switch expresión, pero no puedo usar constantes definidas manualmente, sino solo nombres principales para enumeraciones).

    – Sasha

    15 de noviembre de 2017 a las 11:44


  • Las enumeraciones de @Sasha en Java no tienen números enteros asignados como en C++. Son abstractos como java boolean.

    – usuario13947194

    31 de julio de 2021 a las 15:59

  • @ user13947194, nadie dijo que sí. Acabo de señalar la falacia lógica: para un tipo podemos usar tanto los literales primarios como las constantes definidas manualmente, mientras que para el otro tipo podemos usar solo nombres primarios pero no constantes definidas manualmente.

    – Sasha

    15 de enero a las 14:27

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

De JAVA14 en adelante, se pueden usar expresiones de cambio.

para esta publicación

public enum MyEnum {
    VALUE_A, VALUE_B;
}
public void someMethod() { 
    MyEnum enumExample //...

    switch (enumExample) {
        case VALUE_A -> {
            // logic
        }
        case VALUE_B -> {
            // logic
        }   
    }
}

Cambiar expresión

Como todas las expresiones, las expresiones de cambio se evalúan en un solo valor y se pueden usar en declaraciones. Pueden contener etiquetas “caso L ->” que eliminan la necesidad de declaraciones de interrupción para evitar fallas. Puede usar una declaración de rendimiento para especificar el valor de una expresión de cambio.

public enum Month {
    JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC;
}

Ejemplo 1: Devuelve valor.

public static int getNoOfDaysInAMonth(Month month, boolean isLeapYear) {
    return switch(month) {
        case APR, JUN, SEP, NOV -> 30;
        case FEB -> (isLeapYear)? 29: 28;
        case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31;
    };
}

Ejemplo 2: No devuelve valor.

public static void printNoOfDaysInAMonth(Month month, boolean isLeapYear) {
    switch(month) {
        case APR, JUN, SEP, NOV -> {
            System.out.println("30 days");
        }
        case FEB -> {
            System.out.println(((isLeapYear)? 29: 28) + " days");
        }
        case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> {
            System.out.println("31 days");
        }
    };
}

Referencia

Cambiar expresiones

avatar de usuario
jimit patel

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-case Como se muestra abajo

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

avatar de usuario
guion1e

Escribe someMethod() De este modo:

public void someMethod() {

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

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

En la declaración de cambio, debe usar solo el nombre de la constante.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad