valueof unqualified the switch name must enum constant con java enums constants case switch-statement

java - unqualified - Por qué "int. Final estático" se puede usar como una constante de mayúsculas y minúsculas pero no como "estática final<su enumeración>"



switch java (5)

¿Por qué es válido este interruptor int:

public class Foo { private final static int ONE = 1; private final static int TWO = 2; public static void main(String[] args) { int value = 1; switch (value) { case ONE: break; case TWO: break; } } }

Mientras que este interruptor de enumeración no es:

import java.lang.annotation.RetentionPolicy; public class Foo { private final static RetentionPolicy RT = RetentionPolicy.RUNTIME; private final static RetentionPolicy SRC = RetentionPolicy.SOURCE; public static void main(String[] args) { RetentionPolicy value = RetentionPolicy.RUNTIME; switch (value) { case RT: break; case SRC: break; } } }

Sé que lo que sucede en el caso debe ser una constante, así que ¿por qué puedo usar una "int estática final" como constante pero no una "estática final <su enumeración>"?


El argumento del caso debe ser primitivo; no puede ser un objeto.

Sin embargo, puede utilizar enumeraciones de la siguiente manera:

RetentionPolicy value = ... switch (value) { case RUNTIME: case SOURCE: }

Debido a value se declara que el value es del tipo RetentionPolicy , puede usar las constantes de enumeración directamente dentro del conmutador.


El compilador dice

unqualified enumeration constant name required

Por lo tanto, su valor de RT tendría que ser RUNTIME lugar de RetentionPolicy.RUNTIME para que su código funcione. Pero claro que eso no es posible. ¿Por qué no usar la enumeración RetentionPolicy directamente? Si desea atenerse a su declaración estática final, debe asignar la enumeración completa a su variable estática final.


O simplemente use un caso if-elseif:

private final static int ONE = 1; private final static int TWO = 2; public static void main(String[] args) { int value = 1; if(value.equals(ONE)){ } else if(value.equals(ONE)){ } }


Porque una etiqueta de declaración de caso debe tener una constante de tiempo de compilación o un EnumConstantName. JLS 14.11

Las constantes de tiempo de compilación solo pueden ser cadenas y tipos primitivos, como se describe en JLS 15.28 . Por lo tanto, no puede usar una final estática <su enumeración>, ya que no es una constante de tiempo de compilación ni el nombre de una enumeración.


Tenía un requisito similar y resolví este problema cambiando el número ordinal de Enums en lugar de encender el enum mismo. Esto no es muy bonito / intuitivo pero funciona:

public class Foo { private final static int SRC = 0; // == RetentionPolicy.SOURCE.ordinal(); private final static int RT = 2; // == RetentionPolicy.RUNTIME.ordinal(); static{ if (RT != RetentionPolicy.RUNTIME.ordinal() || SRC != RetentionPolicy.SOURCE.ordinal()) { throw new IllegalStateException("Incompatible RetentionPolicy.class file"); } } public static void main(String[] args) { RetentionPolicy value = RetentionPolicy.RUNTIME; switch (value.ordinal()) { case RT: break; case SRC: break; } } }

Tenga en cuenta que, por supuesto, no es posible declarar la constante como, por ejemplo,

private final static int SRC = RetentionPolicy.SOURCE.ordinal();

por la misma razón, uno no puede declarar la constante como un Enum en primer lugar ...