views:

416

answers:

3

Hi,

In Java, a for-each loop.
If I have a method that generates an array, called genArray().

In the following code, will the array each time be re-generated by calling genArray()? Or will Java call once the method and store a copy from the array?

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

Thanks

+5  A: 

Java will call genArray() once, get the iterator object, and call that multiple times.

John Stauffer
This answer is partially **wrong**. Yes, Java will call `genArray()` only once but, no, `java.lang.Array` isn't a subtype of `Iterable` so Java won't get an iterator object.
Pascal Thivent
+4  A: 

It should only get used once - it's the same as calling this:

  String[] strings = genArray();
  for (String s : strings) {
  ...
mjd79
+12  A: 

About the enhanced for statement, the Java Language Specifications writes:

The enhanced for statement has the form:

EnhancedForStatement:
        for ( VariableModifiersopt Type Identifier: Expression) Statement

The Expression must either have type Iterable or else it must be of an array type (§10.1), or a compile-time error occurs.

The scope of a local variable declared in the FormalParameter part of an enhanced for statement (§14.14) is the contained Statement

The meaning of the enhanced for statement is given by translation into a basic for statement.

If the type of Expression is a subtype of Iterable, then let I be the type of the expression Expression.iterator(). The enhanced for statement is equivalent to a basic for statement of the form:

for (I #i = Expression.iterator(); #i.hasNext(); ) {

        VariableModifiersopt Type Identifier = #i.next();
   Statement
}

Where #i is a compiler-generated identifier that is distinct from any other identifiers (compiler-generated or otherwise) that are in scope (§6.3) at the point where the enhanced for statement occurs.

Otherwise, the Expression necessarily has an array type, T[]. Let L1 ... Lm be the (possibly empty) sequence of labels immediately preceding the enhanced for statement. Then the meaning of the enhanced for statement is given by the following basic for statement:

T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
        VariableModifiersopt Type Identifier = a[i];
        Statement
}

Where a and i are compiler-generated identifiers that are distinct from any other identifiers (compiler-generated or otherwise) that are in scope at the point where the enhanced for statement occurs.

So in your case, genArray() doesn't return a subtype of Iterable but an array type, so your enhanced for statement is equivalent to the following basic for statement:

String[] a = genArray();
...
for (int i = 0; i < a.length; i++) {
    String s = a[i];
    // ...
}

And genArray() will thus be called only once (but the currently accepted answer is partially wrong).

Pascal Thivent