【发布时间】:2011-03-18 21:53:58
【问题描述】:
如果有一个方法调用 MyClass.returnArray() 并且我使用 for-each 构造(也称为“增强型 for”循环)遍历数组:
for (ArrayElement e : MyClass.returnArray()) {
//do something
}
那么每次迭代都会调用returnArray() 方法吗?
【问题讨论】:
如果有一个方法调用 MyClass.returnArray() 并且我使用 for-each 构造(也称为“增强型 for”循环)遍历数组:
for (ArrayElement e : MyClass.returnArray()) {
//do something
}
那么每次迭代都会调用returnArray() 方法吗?
【问题讨论】:
不,不会。第一次调用的结果将存储在编译后的代码中的一个临时变量中。
来自Effective Java 2nd. Ed.,第 46 条:
请注意,使用没有性能损失 for-each 循环,即使对于数组也是如此。事实上,它可能会提供轻微的性能优势 在某些情况下,通过普通的 for 循环,因为它计算了 数组索引只有一次。
【讨论】:
returnArray方法只被调用了一次。
EnhancedForStatement:
for ( VariableModifiersopt Type Identifier: Expression) Statement
及以后:
T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
VariableModifiersopt Type Identifier = a[i];
Statement
}
这(在伪代码中)相当于用于数组的高级 for 循环。并且很清楚,Expression 被评估一次,结果数组被分配给T[] a。
因此,即使在高级 for 循环语句中使用复杂的表达式也是完全安全的。
【讨论】:
没有。
for 循环只是语法糖。它的行为 differently 取决于它是否应用于 Array 参数或实现 Iterable 接口的对象。
对于 Iterable 对象,循环扩展为如下内容:
Iterator<ArrayElement> iter = iterableObject.iterator();
while (iter.hasNext()) {
ArrayElement e = iter.next();
// do smth
}
您的示例代码实际上是这样的:
Object[] temp = Method.returnArray();
for ( int i = 0; i < temp.length; i++ ) {
ArrayElement e = (ArrayElement) temp[i];
// do smth
}
【讨论】:
Iterable 的所有子类都是完全正确的,但高级 for 循环也可以与数组一起使用,我想这就是问题的重点。它仍然是“语法糖”,但有点不同。
不,它会被调用一次。它不像标准 for 循环的终止条件,它在每次迭代时都会被评估。
【讨论】: