Почему локальная переменная расширенного цикла for должна быть локальной? [дубликат]

На этот вопрос уже есть ответ здесь:

Согласно Спецификации языка Java, § 14.14.2 , переменная расширенного цикла for должна быть локальной для цикла.Другими словами, это компилирует:

for (State state : State.values()) {
    // do something for each state
}

, но не делает:

State state;
for (state: State.values()) {
    // do something for each state
}

JLS не дает никакого объяснения этому выбору дизайна языка. Я могу понять, почему имя типа должно присутствовать, если локальная переменная изменена final или аннотацией, но я не понимаю, почему голое имя переменной, объявленной где-то еще, не допускается. Есть ли у кого-нибудь представление о том, почему было наложено это ограничение?

РЕДАКТИРОВАТЬ

Некоторые ответы, похоже, предполагают, что то, что происходит вне цикла, является причиной для разработки языка таким образом. Возможно, более пристальное изучение того, что говорит JLS, прояснит, почему я не считаю это убедительным. Рассмотрим этот цикл, где State - это перечисление:

for (State state : State.values()) {
    // ...
}

State.values ​​() - это массив, поэтому, согласно JLS, цикл функционально идентичен:

State[] a = State.values();
for (int i = 0; i < a.length; i++) {
    State state = a[i];
    // ...
}

Теперь ясно, что это последний цикл можно было бы записать:

State state;
State[] a = State.values();
for (int i = 0; i < a.length; i++) {
    state = a[i];
    // ...
}

Концептуально этот последний (совершенно законный) цикл мог бы использоваться как функциональный эквивалент второго расширенного цикла for выше (того, который не компилируется).

Аналогично, если stateList является Iterable (не массивом), этот цикл:

for (State state : stateList) {
    // ...
}

функционально идентичен:

for (Iterator iterator = stateList.iterator(); iterator.hasNext(); ) {
    State state = iterator.next();
    // ...
}

Как и раньше, последний цикл можно было бы записать:

State state;
for (Iterator iterator = stateList.iterator(); iterator.hasNext(); ) {
    state = iterator.next();
    // ...
}

Опять же, этот мог использоваться как функциональный эквивалент (недопустимого):

State state;
for (state : stateList) {
    // ...
}

В каждом случае, когда цикл завершается, значение состояния прекрасно определено (если, возможно, бесполезно).Кроме того, как и в случае с обычным циклом, расширенный цикл for , использующий пустое имя переменной, которое не было определено (например, строка State state; отсутствовала или выходила за рамки) быть пойманным во время компиляции. Итак, в чем проблема с точки зрения языкового дизайна? Почему разработчики языка объявили эту конструкцию вне закона?

32
задан Mechanical snail 25 January 2013 в 23:54
поделиться