2012-05-30 22 views
81

Tengo una pregunta loca sobre los conmutadores Java.Declaración e inicialización de variables dentro de los conmutadores 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 case 2: que grazna diciendo que el El valor de la variable local no puede tener sido inicializado.

Preguntas:

Escenario 1: Si el flujo de ejecución no va a case 1: (cuando el key = 2), entonces ¿cómo sabe el tipo de la variable de valor como int?

Escenario 2: si el compilador conoce el tipo de la variable de valor como int, entonces debe haber accedido a la expresión int value = 1; en case 1:. (Declaración e inicialización). Entonces, ¿por qué sqawrk? Cuando voy a comentar value = 2 en case 2:, diciendo El valor de la variable local puede no haberse inicializado.

+9

No es una pregunta loca, es una muy buena pregunta. – biziclop

+0

Posible duplicado del [Alcance de la variable en una caja de conmutadores] (http://stackoverflow.com/questions/3894119/variables-scope-in-a-switch-case) –

+0

@PhilippeCarriere En realidad, creo que debería ser al revés - la respuesta aquí es mejor (incluso si la publicación es más reciente) ya que hay una referencia directa al JLS, y resume bien el problema cubierto en las diferentes respuestas en esa publicación. [Ver también] (http://meta.stackoverflow.com/questions/251938/should-i-flag-a-question-as-duplicate-if-it-has-received-better-answers). – Tunaki

Respuesta

96

Las declaraciones de interruptor son extrañas en términos de alcance, básicamente. De section 6.3 of the JLS:

El alcance de una declaración de variable local en un bloque (§14.4) es el resto del bloque en el que aparece la declaración, a partir de su propia inicializador y que incluye cualquier declaradores más a la derecha en el declaración de declaración de variable local.

En su caso, case 2 es en el mismo bloque de como case 1 y aparece después de que, a pesar de que nunca se ejecutará case 1 ... por lo que la variable local es en su alcance y disponible para escribir pesar de que lógicamente nunca "ejecutando" la declaración. (Una declaración no es realmente "ejecutable" aunque la inicialización sí lo es).)

Si comenta la asignación value = 2;, el compilador aún sabe a qué variable se refiere, pero no habrá pasado por ninguna ruta de ejecución que le asigna un valor, por lo que se obtiene un error como lo haría cuando intente leer cualquier otra variable local no asignada definitivamente.

Le recomendaría encarecidamente no para usar las variables locales declaradas en otros casos - conduce a un código altamente confuso, como ha visto. Cuando introduzco variables locales en los estados de conmutación (que yo trato de hacer raramente - los casos deben ser muy cortos, lo ideal) Por lo general prefieren a introducir un nuevo ámbito:

case 1: { 
    int value = 1; 
    ... 
    break; 
} 
case 2: { 
    int value = 2; 
    ... 
    break; 
} 

Creo que esto es más claro.

+8

+1 para "Una declaración no es realmente" ejecutable "aunque la inicialización es". Y gracias por los consejos también Skeet. – namalfernandolk

18

Desde http://www.coderanch.com/t/447381/java-programmer-SCJP/certification/variable-initialization-within-case-block

declaraciones se procesan en tiempo de compilación y no dependen del flujo ejecución del código. Dado que value se declara dentro del alcance local del bloque de conmutadores, se puede usar en cualquier punto de ese bloque desde el punto de su declaración.

+0

¿por qué esta respuesta se está votando? no responde la pregunta, a diferencia de la respuesta de paul o skeet ... –

+6

Lo hace. Entonces, +1, un centavo, de mi lado también. –

18

La variable ha sido declarada (como un int), pero no inicializada (se le ha asignado un valor inicial). Piense en la línea:

int value = 1; 

Como:

int value; 
value = 1; 

La parte int value le dice al compilador en tiempo de compilación que tiene un valor de la variable llamada que es un int. La parte value = 1 lo inicializa, pero eso sucede en tiempo de ejecución y no ocurre en absoluto si no se ingresa esa rama del conmutador.

+0

+1 para una buena explicación de la declaración y la inicialización en tiempo de compilación y tiempo de ejecución. – namalfernandolk

Cuestiones relacionadas