Почему переменные, определенные в блоке case, доступны в других блоках case?
Возможный дубликат:
Почему переменные не локальны в операторах case?
Переменная, определенная в блоке области видимости, не может использоваться вне нее. Например, следующий фрагмент кода недействителен:
{
int anothervar = 4;
}
{
System.out.println(anothervar);
}
Но похоже, что блок case
не создает отдельные области.
switch (mode) {
case ONE:
dosomething();
return;
case TWO:
int[] someints = new int[] { 2, 3, 5, 7 };
SomeObject obj = new SomeObject();
return;
case THREE:
someints = new int[] { 1, 4, 6, 8, 9 };
obj = new SomeObject();
return;
}
Почему мне не нужно объявлять someints
внутри блока case THREE
?
Предположим mode = THREE
, тогда объявление переменной someints
никогда не будет достигнуто, потому что case TWO
, где объявлено someints
, пропускается. Или не так ли? Как это работает внутри?
(Выбранный ответ в Почему переменные не локальны в операторах case? утверждает, что оператор switch является внутренним набором команд jump
, но все же это делает не объяснять, где объявлена переменная someints
.)
Ответы
Ответ 1
локальная область переменных находится внутри блока, как указано в Документация по именам:
Объем объявления локальной переменной в блоке (§14.4.2) - это остальной части блока, в котором появляется декларация, начиная с ее (§14.4) и включая любые последующие деклараторы для прямо в локальном объявлении переменной.
Определен блок, который имеет охватывающие фигурные скобки, как написано также в Блок-фактура и документация:
Блок представляет собой последовательность операторов, объявлений локального класса и локальные инструкции объявления переменных в фигурных скобках.
Ответ 2
Все внутри { }
находится в одной области. Если вы выберете return;
в случае TWO, например, вы можете использовать переменную в случае ТРИ, если она инициализирована.
Ответ 3
Вот почему вы иногда видите код с:
case 0: {
// Stuff
}
Только {} разделяет блоки.
Ответ 4
Объем объявления помечен { ... }
, и вы можете упасть с одного случая за секунду. Я признаю, что это дыра. Я верю в более старую версию Java, которой не разрешалось объявлять на уровне case
и приходилось добавлять дополнительные фигурные скобки:
case 1: { int x; ... }
Ответ 5
В дополнение к другим ответчикам (как они заметили, область действия между {} является только одной здесь), я хотел бы заметить, что такая практика: объявление переменной в одном случае и использование ее в другой, загрязнен. Позже вы можете удалить или изменить какой-либо случай. И если он будет с декларацией, вам придется изменить другой случай. Это может привести к ошибкам.
Подумайте, почему ваша переменная должна быть в обоих случаях? Это ДЕЙСТВИТЕЛЬНО одно и то же или два разных?
Если это то же самое:
Лучше объявите общие переменные в случае по умолчанию и поставьте его как первый.
switch (mode) {
default:
int[] someints;
return;
case ONE:
dosomething();
return;
case TWO:
someints = new int[] { 2, 3, 5, 7 };
SomeObject obj = new SomeObject();
return;
case THREE:
someints = new int[] { 1, 4, 6, 8, 9 };
obj = new SomeObject();
return;
}
Или объявите их из блока переключателей (это хуже). Или поместите его где-нибудь, где вы определяете константы.
Если они действительно являются разными переменными (может быть как-то схожи):
определите в каждом случае другую переменную.
Кстати: Это действительно хороший вопрос!