2009-10-24 53 views
8

在Java中,for-each循环。
如果我有一个方法可以生成一个名为genArray()的数组。在java增强for循环中,假设循环表达式只会被评估一次是否安全?

在下面的代码中,每次都会通过调用genArray()来重新生成数组? 或者Java会调用一次方法并从数组中存储一份副本?

for (String s : genArray()) 
{ 
    //... 
} 

感谢

+3

当然,最容易知道的方法是测试一下... genArray()中的一个简单的System.out.println()就足够了! – PhiLho 2009-10-24 15:09:49

+0

[Java foreach效率]的可能重复(http://stackoverflow.com/questions/904582/java-foreach-efficiency) – 2010-12-05 00:14:27

回答

23

关于the enhanced for statement,在Java语言规范写道:

增强的for语句的 形式:

EnhancedForStatement: 
     for (VariableModifiersopt Type Identifier: Expression) Statement 

表达式必须有类型 Iterable,否则它必须是 数组类型(第10.1节),或编译时 发生错误。

一个局部变量的范围在 增强for声明(§14.14)的FormalParameter部分申报 是 所包含的声明

增强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语句 的 意义由以下基本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()将因此只被调用一次(但目前接受的答案部分错误)。

5

Java将调用genArray()一次,获得iterator对象,并调用多次。

+5

这个答案部分**错误**。是的,Java只会调用'genArray()'一次,但不,''java.lang.Array'不是'Iterable'的子类型,因此Java不会获得迭代器对象。 – 2009-10-24 16:16:14

5

它应该只习惯于一次 - 这是与调用此:

String[] strings = genArray(); 
    for (String s : strings) { 
    ...