以下内容:
for (String deviceNetwork : deviceOrganizer.getNetworkTypes(deviceManufacturer)) {
// do something
}
是否可以安全地假设 deviceOrganizer.getNetworkTypes(deviceManufacturer)只会被调用一次?
答案 0 :(得分:18)
是的,绝对。
来自section 14.14.2 of the spec:
如果Expression的类型是Iterable的子类型,那么让我成为Iterable的类型 表达式Expression.iterator()。增强的for语句相当于一个基本的for 表格声明:
for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement }
(替代方案涉及数组。)
注意如何在for循环表达式的第一部分中提到Expression
- 所以它只被评估一次。
答案 1 :(得分:7)
是的,试一试:
public class ForLoop {
public static void main( String [] args ) {
for( int i : testData() ){
System.out.println(i);
}
}
public static int[] testData() {
System.out.println("Test data invoked");
return new int[]{1,2,3,4};
}
}
输出:
$ java ForLoop
Test data invoked
1
2
3
4
答案 2 :(得分:1)
为了补充已经说过的内容并验证规范是否正在执行它所说的内容,让我们看一下下面类生成的字节码,它实现旧的和新的样式循环来循环遍历方法调用返回的列表{ {1}}:
getList()
输出的相关部分:
public class Main {
static java.util.List getList() { return new java.util.ArrayList(); }
public static void main(String[] args) {
for (Object o : getList()) {
System.out.print(o);
}
for (java.util.Iterator itr = getList().iterator(); itr.hasNext(); ) {
Object o = itr.next(); System.out.print(o);
}
}
}
这表明第一个循环(0到32)和第二个循环(35-67)相同。
生成的字节码完全相同。