Следующий код Java бросает ошибку компилятора:
if ( checkGameTitle(currGame) )
ArrayList<String> items = parseColumns( tRows.get(rowOffset+1), currGame, time, method );
checkGameTitle
общедоступная статическая функция, возвращая булевскую переменную. Ошибки все имеют тип, "не может найти символ" с символом тем, чтобы быть variable ArrayList
, variable String
и variable items
.
Однако, если я добавляю {фигурные скобки} затем компиляции кода без ошибок. Почему это могло бы быть? Есть ли некоторая неоднозначность на if
пункт без них?
Если вы объявите переменную items
на этом этапе, она будет недоступна из любого места. Так что допустить такую конструкцию не имело бы смысла.
OTOH, когда вы открываете блок, все равно нет смысла делать то же самое (сначала). Но ожидается, что вы захотите расширить блок позже, и что в конечном итоге это будет иметь смысл.
Проблема в том, что это:
if ( condition )
ArrayList<String> items = ...;
... по сути эквивалентно этому:
if ( condition ) {
ArrayList<String> items = ...;
}
Вы определили и инициализировали элементов
, но когда вы выходите из оператора / блокируете его вне области видимости, поэтому вы не можете использовать его ни для чего. Компилятор предупреждает вас об этом.
С фигурными скобками вы создаете блок, который может содержать объявления. Без фигурных скобок вы можете иметь только утверждение, а не декларацию, как в вашем примере
Вы определяете переменную items
в операторе if, поэтому она не может быть использована нигде за пределами этой области.
EDIT: Слишком медленно...
Ошибка компилятора возникает из-за того, что правила языка не дают четкого указания на объем объявления переменной "items".
Например, если у меня есть такой блок кода:
bool isTrue() {
bool returnValue = false;
if (cheese.isGreen()) {
returnValue = true;
}
return returnValue;
}
до боли ясно, что returnValue является допустимой переменной для всего метода.
Если у меня есть такой блок кода:
bool isTrue() {
if (cheese.isGreen()) {
bool returnValue = true;
}
return returnValue;
}
до боли ясно, что returnValue недействителен вне «условия if».
Но если у меня есть такой блок кода:
bool isTrue() {
if (cheese.isGreen())
bool returnValue = true;
return returnValue;
}
неясно, входит ли returnValue в область действия оператора if или returnValue в область действия всего метода. Это связано с деталями структуры грамматики языка Java. По сути, разрешено объявлять новые переменные в любом блоке (поскольку блок четко определяет область действия переменной), но этот оператор if не содержит блока.
Если вы предполагаете, что Java добавляет блок за вас молча, тогда область действия находится в пределах «забытого блока». Если вы предполагаете, что, поскольку нет явного блока для содержания области, тогда область видимости переменной находится на том же уровне, что и остальная часть метода. Существует множество аргументов относительно того, какая точка зрения «более» верна, поэтому всякая попытка сделать это запрещена.
Если это кажется вам странным, и вы считаете, что только сумасшедший не мог бы предположить, что переменная определена в рамках подразумеваемого блока, пожалуйста, помните, что существовали языки до Java, в которых область видимости была на уровне на том же уровне, что и оператор возврата. Да, безумные языки по сегодняшним меркам, но они все еще существовали.
Просто потому, что я думаю, что это всегда полезно в таких ситуациях, соответствующая часть спецификации языка Java здесь §14.4 :
Объявление каждой локальной переменной оператор сразу содержится в блоке. Операторы объявления локальной переменной могут свободно смешиваться с операторами других типов в блоке.
Другими словами, объявления локальных переменных могут появляться только как отдельные объявления на уровне непосредственно «ниже» блока ( {}
). Они не считаются Утверждениями
(§14.5), которые идут после if (....)
.