7

¿Cómo maneja el compilador Java el siguiente bloque de conmutadores? ¿Cuál es el alcance de la variable 'b'?Conmutador Java: declaración de variable y alcance

Tenga en cuenta que la variable 'b' se declara solo en la primera rama de la instrucción switch. Intentar declararlo en la segunda rama también produce un error de compilación de "variable local duplicada".

int a = 3; 
    switch(a) { 
    case 0: 
     int b = 1; 
     System.out.println("case 0: b = " + b); 
     break; 
    case 1: 
     // the following line does not compile: b may not have been initialized 
     // System.out.println("case 1 before: b = " + b); 
     b = 2; 
     System.out.println("case 1 after: b = " + b); 
     break; 
    default: 
     b = 7; 
     System.out.println("default: b = " + b); 
    } 

Nota: el código anterior se compila con un compilador de Java 1.6.

+0

Respondido su propia pregunta. – darrengorman

Respuesta

21

El alcance está, como de costumbre, delimitado por { y }.

+7

Mensaje a OP, puedes poner llaves alrededor de cada caso y luego funcionaría. Como en 'caso 1: {doHere(); descanso; } ' – jn1kk

10

El alcance de b es el bloque. Solo tiene un bloque que incluye todos los case s. Es por eso que obtienes un error de compilación cuando redeclaras b en tu segundo case.

Se puede envolver cada case en un bloque propio como

case 0: 
    { 
    int b = 1; 
    ... 
    } 
case 1: 
    { 
    int b = 2; 
    ... 
    } 

pero creo FindBugs o CheckStyle se queja de eso.

+4

El error de compilación no proviene de _redeclaring_' b', sino de acceder a él antes de inicializarlo. 'b' es perfectamente válido en el caso 0, 1 y por defecto porque como mencionas está en el alcance.El problema con su línea comentada que no se compila es que b no se inicializa antes de acceder. – NominSim

+0

Debería haber leído la pregunta con más cuidado. Pensé que estaba haciendo 'int b = 2' en la línea comentada ;-) – Kai

0

Sus bloques case no tienen ningún ámbito local. No es una serie de if ... else if ... else bloques, java lo implementa como una serie de GOTO s.

3

El alcance de b es el bloque de interruptores - entre la declaración y el delimitador } -

int a = 3; 

switch(a) { 
    case 0: 
      int b = 1; //scope starts 
      System.out.println("case 0: b = " + b); 
      break; 
    case 1: 
      // the following line does not compile: b may not have been initialized 
      // System.out.println("case 1 before: b = " + b); 
      b = 2; 
      System.out.println("case 1 after: b = " + b); 
      break; 
    default: 
      b = 7; 
      System.out.println("default: b = " + b); 
}//scope ends 

Sin embargo, es necesario saber que si se declara la int b dentro del case 1:, usted no tendrá acceso a b la variable dentro del case 0:

Para responder a la pregunta que haces en el java los comentarios se puede comprobar este ejemplo sencillo:

int b; 
if(true){ 
    b++; //The local variable b hast not been initialized 
} 

Espero que ayude.

1

en su código si a no es igual a 0 b nunca se inicializará. usted debe definir b antes de la declaración de cambio.

+0

El problema está en tiempo de compilación, no en tiempo de ejecución. –

0

El alcance de las variables definidas en una declaración switch() sería el mismo que en un bloque normal que está rodeado por { y }.

Por lo tanto, cada variable definida en una declaración switch() es visible para todo el bloque, una vez que está definido.

3

Puede definir el alcance usando {} alrededor de su caja.

int a = 3; 
switch(a) { 
case 0: { 
    int b = 1; 
    System.out.println("case 0: b = " + b); 
    break; 
} 
case 1: { 
    // the following line does not compile: b may not have been initialized 
    // System.out.println("case 1 before: b = " + b); 
    int b = 2; 
    System.out.println("case 1 after: b = " + b); 
    break; 
} 
default: { 
    int b = 7; 
    System.out.println("default: b = " + b); 
} 
}