在java增强的for循环中,可以安全地假设要循环的表达式只会被评估一次吗?

时间:2010-04-21 21:10:49

标签: java

以下内容:

for (String deviceNetwork : deviceOrganizer.getNetworkTypes(deviceManufacturer)) {
    // do something
}

是否可以安全地假设 deviceOrganizer.getNetworkTypes(deviceManufacturer)只会被调用一次?

3 个答案:

答案 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)相同
生成的字节码完全相同