在java增强的for循环中,可以安全地假设要循环的表达式只会被评估一次吗?
题
在Java中,for-each循环。
如果我有一个生成数组的方法,名为 genArray()
。
在下面的代码中,每次通过调用 genArray()
重新生成数组?
或者Java会调用一次方法并从数组中存储副本吗?
for (String s : genArray())
{
//...
}
由于
解决方案
关于增强的陈述,Java语言规范写道:
增强的for语句有 形式:
EnhancedForStatement: for ( VariableModifiersopt Type Identifier: Expression) Statement
Expression必须具有类型
Iterable
或者它必须是 数组类型(§ 10.1),或编译时 发生错误。声明的局部变量的范围 在FormalParameter中的一部分 增强的
for
语句(§ 14.14)是 包含的声明的增强
的含义 声明是通过翻译给出的
语句的基本。
如果
Expression
的类型是aIterable
的子类型,然后让I
成为 表达式的类型 表达。 <代码>迭代器()代码>。增强的for
语句是等效的 到的基本语句 形式:
for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement }
其中
#i
是编译器生成的 与任何不同的标识符 其他标识符(编译器生成的 或者)在范围内(&#167; 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 }
其中 a 和 i 是编译器生成的 与任何不同的标识符 其他标识符(编译器生成的 或者其他)在范围内 点在哪里增强for语句 发生。
所以在你的情况下, genArray()
不会返回 Iterable
的子类型,而是返回一个数组类型,所以你的增强 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) {
...