Можно ли предположить, что в расширенном цикле Java for циклическое выражение будет оцениваться только один раз?

StackOverflow https://stackoverflow.com/questions/1618202

Вопрос

В Java есть цикл for-each.
Если у меня есть метод, который генерирует массив, называемый genArray().

В следующем коде массив будет каждый раз заново генерироваться путем вызова genArray()?Или Java вызовет метод один раз и сохранит копию из массива?

for (String s : genArray())
{
    //...
}

Спасибо

Это было полезно?

Решение

О расширенное заявление, в спецификациях языка Java написано:

Увеличение для заявления имеет форму:

EnhancedForStatement:
        for ( VariableModifiersopt Type Identifier: Expression) Statement

Выражение должно иметь тип Iterable Или же это должно быть типа массива (§10.1), или возникает ошибка времени компиляции.

Объем локальной переменной, объявленной в формальпараметре for Заявление (§14.14) является содержательным утверждением

Смысл расширенного forЗаявление дано переводом в базовый for заявление.

Если тип Expression является подтипом Iterable, тогда пусть I быть типом выражения Выражение.iterator().Расширенный for утверждение эквивалентно базовому for утверждение формы:

for (I #i = Expression.iterator(); #i.hasNext(); ) {

        VariableModifiersopt Type Identifier = #i.next();
   Statement
}

Где #i является созданным компилятором идентификатором, который отличается от любых других идентификаторов (сгенерированных компиляторами или иным образом), которые находятся в области (§6.3) в точке, где происходит усиление для утверждения.

В противном случае выражение обязательно имеет тип массива, T[].Позволять L1 ... Lmбыть (возможно пустой) последовательность меток, непосредственно предшествующих усилению for заявление.Тогда значение усиления для утверждения определяется следующим базовым forзаявление:

T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
        VariableModifiersopt Type Identifier = a[i];
        Statement
}

Где а и я являются сгенерированными компиляторами идентификаторами, которые отличаются от любых других идентификаторов (сгенерированных компиляторами или иным образом), которые находятся в объеме в точке, где происходит усиление для утверждения.

Итак, в вашем случае genArray() не возвращает подтип Iterable но тип массива, поэтому ваш расширенный for утверждение эквивалентно следующему базовому for заявление:

String[] a = genArray();
...
for (int i = 0; i < a.length; i++) {
    String s = a[i];
    // ...
}

И genArray() таким образом, будет вызываться только один раз (но принятый в настоящее время ответ частично неверен).

Другие советы

Java вызовет genArray() один раз, получит объект итератора и вызовет его несколько раз.

Его следует использовать только один раз — это то же самое, что вызвать это:

  String[] strings = genArray();
  for (String s : strings) {
  ...
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top