Нечетная ошибка компилятора в условии if без фигурных скобок - PullRequest
5 голосов
/ 27 марта 2010

Следующий код Java вызывает ошибку компилятора:

if ( checkGameTitle(currGame) )
    ArrayList<String> items = parseColumns( tRows.get(rowOffset+1), currGame, time, method );

checkGameTitle является публичной статической функцией, возвращающей логическое значение. Все ошибки относятся к типу «не удается найти символ» с символами variable ArrayList, variable String и variable items.

Однако, если я добавлю {фигурные скобки}, тогда код будет скомпилирован без ошибок . Почему это может быть? Есть ли некоторая двусмысленность в предложении if без них?

Ответы [ 6 ]

11 голосов
/ 27 марта 2010

Если вы объявите переменную items в этот момент, она нигде не будет доступна. Так что не имеет смысла разрешать эту конструкцию.

OTOH, когда вы открываете блок, все равно не имеет смысла делать то же самое (сначала). Но ожидается, что вы захотите расширить блок позже, и в конечном итоге это будет иметь смысл.

4 голосов
/ 27 марта 2010

С помощью фигурных скобок вы создаете блок, который может содержать объявления.Без фигурных скобок вы можете иметь только утверждение, а не объявление, такое как ваш пример

2 голосов
/ 27 марта 2010

Только потому, что я думаю, что это всегда полезно в этих ситуациях, соответствующая часть спецификации языка Java здесь §14.4 :

Каждый оператор объявления локальной переменной немедленно содержится в блоке. Операторы объявления локальных переменных могут свободно смешиваться с другими типами операторов в блоке.

Другими словами, объявления локальных переменных могут появляться только как отдельные объявления на уровне, который находится непосредственно «под» блоком ({}). Они не учитываются как Statements (§14.5), которые идут после if (....).

1 голос
/ 27 марта 2010

Проблема в том, что это:

if ( condition )
    ArrayList<String> items = ...;

... по существу эквивалентно этому:

if ( condition ) {
    ArrayList<String> items = ...;
}

Вы определили и инициализировали items, но когда вы выходите из оператора / блока, он выходит из области видимости, поэтому вы не можете его использовать ни для чего. Об этом предупреждает компилятор.

0 голосов
/ 27 марта 2010

Ошибка компилятора в том, что правила языка не дают четкого представления о сфере действия объявления переменных "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 существовали языки, где область действия была бы на уровне тот же уровень, что и оператор возврата. Да, сумасшедшие языки по сегодняшним меркам, но они все же существовали.

0 голосов
/ 27 марта 2010

Вы определяете переменную items в операторе if, поэтому ее нельзя будет использовать нигде вне этой области.

РЕДАКТИРОВАТЬ: слишком медленно ...

...