7

Как компилятор Java обрабатывает следующий блок переключателей? Какова область действия переменной «b»?Переключатель Java: объявление переменной и область действия

Обратите внимание, что переменная 'b' объявляется только в первой ветви оператора switch. Попытка объявить его во второй ветви также приводит к ошибке «дублирования локальной переменной».

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); 
    } 

Примечание: приведенный выше код компилируется с помощью компилятора java 1.6.

+0

Ответил на ваш вопрос. – darrengorman

ответ

21

Объем, как обычно, разделен { и }.

+7

Сообщение OP, вы можете поместить фигурные скобки вокруг каждого случая, и тогда это сработает. Как и в случае 1: {doHere(); ломать; } ' – jn1kk

10

Объем b - это блок. У вас есть только один блок, который включает в себя все case s. Вот почему вы получаете ошибку компиляции, когда вы обновляете b во втором case.

Вы можете обернуть каждый case в собственном блоке, как

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

, но я думаю, что FindBugs или CheckStyle бы жаловаться на это.

+4

Ошибка компиляции не от _redeclaring_' b', а от доступа к ней до ее инициализации. 'b' отлично действует в случае 0, 1 и по умолчанию, потому что, как вы говорите, оно находится в области видимости.Проблема с его комментируемой строкой не компиляция заключается в том, что b не инициализируется до того, как он будет доступен. – NominSim

+0

Я должен был прочитать вопрос более осторожным. Я думал, что он делает 'int b = 2' в прокомментированной строке ;-) – Kai

0

Блоки case не имеют локального объема. Это не серия if ... else if ... else блоки, java реализует ее как серию GOTO s.

3

Объем b является блок-переключатель - между объявлением и разделителем } -

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 

Однако, вы должны знать, что если вы объявляете int b внутри case 1:, вы не будете иметь доступ к переменная b внутри case 0:

Чтобы ответить на этот вопрос, вы спросите в Java комментариев вы можете проверить это простой пример:

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

Надеюсь, что это поможет.

1

в вашем коде, если a не равно 0 b, никогда не будет инициализирован. вы должны определить b перед оператором switch.

+0

Проблема заключается во время компиляции, а не во время выполнения. –

0

Объем переменных, определенных в операторе switch(), будет таким же, как в обычном блоке, окруженном { и }.

Поэтому каждая переменная, определенная в операторе switch(), видна для всего блока, как только она определена.

3

Вы можете определить область действия, используя {} вокруг вашего случая.

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); 
} 
} 
Смежные вопросы