У меня сумасшедший вопрос о переключателях Java.
int key = 2;
switch (key) {
case 1:
int value = 1;
break;
case 2:
value = 2;
System.out.println(value);
break;
default:
break;
}
Сценарий 1 - Когда key
это два успешно напечатать значение , как 2.
Сценарий 2 - Когда я буду комментировать value = 2
в case 2:
это коды ответчика говоря , что значение локальной переменной не может быть инициализирован .
Вопросы:
Сценарий 1: Если поток выполнения не переходит case 1:
(когда key = 2
), то как он узнает тип переменной значения как int
?
Сценарий 2: Если компилятор знает тип переменной значения как int
, то он должен иметь доступ к int value = 1;
выражению в case 1:
. (Объявление и инициализация). Тогда почему это sqawrk Когда я буду комментировать value = 2
в case 2:
, говоря , что Значение локальной переменной не может быть инициализирован .
java
scope
initialization
switch-statement
declaration
Намалфернандолк
источник
источник
Ответы:
Операторы switch в основном странны с точки зрения объема. Из раздела 6.3 JLS :
В вашем случае
case 2
находится в том же блоке, чтоcase 1
и, и появляется после него, хотяcase 1
никогда не будет выполняться ... поэтому локальная переменная находится в области видимости и доступна для записи, несмотря на то, что вы логически никогда не «выполняете» объявление. (Объявление не является исполняемым, хотя инициализация есть.)Если вы закомментируете
value = 2;
присвоение, компилятор по-прежнему знает, на какую переменную вы ссылаетесь, но вы не прошли через какой-либо путь выполнения, который присваивает ему значение, поэтому вы получаете сообщение об ошибке, как если бы вы пытались прочтите любую другую локальную переменную с неопределенным назначением.Я настоятельно рекомендую вам не использовать локальные переменные, объявленные в других случаях - как вы видели, это приводит к очень запутанному коду. Когда я ввожу локальные переменные в операторы switch (что я стараюсь делать редко - в идеале случаи должны быть очень короткими), я обычно предпочитаю ввести новую область видимости:
Я считаю, что это яснее.
источник
Переменная была объявлена (как int), но не инициализирована (ей присвоено начальное значение). Подумайте о строчке:
Так как:
Эта
int value
часть сообщает компилятору во время компиляции, что у вас есть переменная с именем value, которая является int.value = 1
Часть инициализирует его, но это происходит во время выполнения, и не бывает вовсе , если эта ветвь переключателя не введена.источник
Из http://www.coderanch.com/t/447381/java-programmer-SCJP/certification/variable-initialization-within-case-block
источник
Благодаря интеграции JEP 325: Switch Expressions (Preview) в сборки раннего доступа JDK-12. Есть определенные изменения, которые можно увидеть из ответа Джона -
Область действия локальной переменной - локальные переменные в вариантах переключения теперь могут быть локальными для самого случая, а не для всего блока переключения . Пример (похожий на то, что Джон пытался синтаксически) с учетом
Day
класса enum для дальнейшего объяснения:Выражения переключения - если намерение состоит в том, чтобы присвоить значение переменной, а затем использовать его, один раз можно использовать выражения переключения. например
источник
Это объяснение может помочь.
источник
Спецификация 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
Помеченные заявления:
Другими словами, case 1, case 2 - это метки внутри оператора switch. К меткам можно применять операторы break и continue.
Поскольку метки разделяют область действия оператора, все переменные, определенные в метках, разделяют область действия оператора switch.
источник