switch example con java switch-statement java-8 constants string-literals

example - switch string java 6



java 8: diferencia entre class.getName() y String literal (3)

Cada etiqueta de caso debe ser una "expresión constante". Qué es "expresión constante" se define en Java Language Standard, §15.28 Expresiones constantes :

Una expresión constante en tiempo de compilación es una expresión que denota un valor de tipo primitivo o una cadena que no se completa abruptamente y se compone solo con lo siguiente:

  • Literales de tipo primitivo y literales de tipo String

...

  • Nombres simples que hacen referencia a variables constantes

No se enumeran las llamadas a los métodos, por lo que el resultado de la llamada al método no puede ser la expresión constante, incluso si el método es trivial. Pero "Nombres simples que hacen referencia a variables constantes" se enumeran aquí, por lo que la referencia a la variable constante también es una constante.

Esta pregunta ya tiene una respuesta aquí:

Estaba trabajando en la caja del interruptor.

Si usamos class.getName (), entonces, recibo el error de que "las expresiones de casos deben ser expresiones constantes" de la siguiente manera:

switch(param.getClass().getName()) { case String.class.getName(): // to do break; }

Incluso si hacemos follow, tome el nombre de la clase de cadena en una constante, y luego, obteniendo el mismo error:

public static final String PARAM_NAME = String.class.getName(); switch(param.getClass().getName()) { case PARAM_NAME: // to do break; }

Pero, si hago follow, use la cadena literal "java.lang.String", no hay error:

public static final String PARAM_NAME = "java.lang.String";

¿Alguien puede explicar esto, por qué no tomar los dos primeros casos y tomar el último? Gracias por adelantado.


classObject.getName() es una llamada a método, y los resultados de las llamadas al método son, por definición, constantes en tiempo de compilación. Un literal de cadena es una constante en tiempo de compilación.

Tenga en cuenta que, si bien muchas situaciones pueden tomar una referencia static final como una constante durante la vida útil del programa, un switch tiene que tener sus opciones codificadas en tiempo de compilación. El valor de un objetivo de case debe ser un valor enum o un (en tiempo de compilación) ConstantExpression .


La razón por la que esto no funciona es que el valor del case para activarlo debe conocerse en tiempo de compilación (porque está codificado y está en línea en el bytecode).

String.class.getName() es una llamada a método que se evalúa en tiempo de ejecución . Sí, static final garantiza que no cambia después de que la clase se carga inicialmente. Pero todo eso es mucho después del tiempo de compilación.

El compilador nunca llama a ningún código del código fuente de la aplicación (con la posible excepción del procesamiento de anotación). Solo lo compila.