Можно ли предположить, что в расширенном цикле Java for циклическое выражение будет оцениваться только один раз?
Вопрос
В 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) {
...