Tengo una pregunta loca sobre los conmutadores de Java.
int key = 2;
switch (key) {
case 1:
int value = 1;
break;
case 2:
value = 2;
System.out.println(value);
break;
default:
break;
}
Escenario 1 - Cuando el key
es dos se imprime con éxito el valor 2.
Escenario 2 - Cuando voy a comentar value = 2
en el case 2:
que chilla diciendo que el valor de la variable local no puede haber sido inicializado .
Preguntas:
Escenario 1: Si el flujo de ejecución no va a case 1:
(cuando key = 2
), ¿cómo sabe el tipo de variable de valor como int
?
Escenario 2: Si el compilador conoce el tipo de variable de valor como int
, entonces debe haber accedido a la int value = 1;
expresión en case 1:
. (Declaración e Inicialización). Entonces ¿por qué lo hace sqawrk Cuando voy a comentar value = 2
en case 2:
, diciendo que el valor de la variable local no puede haber sido inicializado .
java
scope
initialization
switch-statement
declaration
namalfernandolk
fuente
fuente
Respuestas:
Las declaraciones de cambio son extrañas en términos de alcance, básicamente. De la sección 6.3 de la JLS :
En su caso,
case 2
está en el mismo bloque quecase 1
y aparece después, aunquecase 1
nunca se ejecutará ... por lo que la variable local está dentro del alcance y disponible para escribir a pesar de que, lógicamente, nunca "ejecute" la declaración. (Una declaración no es realmente "ejecutable", aunque la inicialización sí lo es).Si comenta la
value = 2;
asignación, el compilador aún sabe a qué variable se refiere, pero no habrá pasado por ninguna ruta de ejecución que le asigne un valor, por lo que obtiene un error como lo haría cuando intenta leer cualquier otra variable local no asignada definitivamente.Le recomendaría encarecidamente que no utilice variables locales declaradas en otros casos, ya que conduce a un código muy confuso, como ha visto. Cuando introduzco variables locales en declaraciones de cambio (lo que trato de hacer rara vez; los casos deberían ser muy cortos, idealmente), generalmente prefiero introducir un nuevo alcance:
Creo que esto está más claro.
fuente
La variable se ha declarado (como un int), pero no se ha inicializado (se le asignó un valor inicial). Piense en la línea:
Como:
La
int value
parte le dice al compilador en tiempo de compilación que tienes una variable llamada valor que es un int. Lavalue = 1
parte lo inicializa, pero eso sucede en tiempo de ejecución y no sucede en absoluto si no se ingresa esa rama del interruptor.fuente
De http://www.coderanch.com/t/447381/java-programmer-SCJP/certification/variable-initialization-within-case-block
fuente
Con la integración de JEP 325: Switch Expressions (Preview) en las compilaciones de acceso temprano JDK-12. Hay ciertos cambios que se pueden ver en la respuesta de Jon :
Alcance de variable local : las variables locales en las cajas de interruptores ahora pueden ser locales para la caja en sí en lugar de todo el bloque de interruptores . Un ejemplo (similar a lo que Jon también había intentado sintácticamente) considerando la
Day
clase enum para una explicación más detallada:Expresiones de cambio : si la intención es asignar un valor a una variable y luego hacer uso de él, una vez puede hacer uso de las expresiones de cambio. p.ej
fuente
Esta explicación podría ayudar.
fuente
Especificaciones de Java:
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.11
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.7
Declaraciones etiquetadas:
En otras palabras, el caso 1, el caso 2 son etiquetas dentro de la instrucción de cambio. Las declaraciones break y continue se pueden aplicar a las etiquetas.
Como las etiquetas comparten el alcance de la declaración, todas las variables definidas dentro de las etiquetas comparten el alcance de la declaración de cambio.
fuente