An enhanced for loop for the Java™ Programming Language



 

I. Introduction

The current for loop construct is powerful, but somewhat ill-suited to iteration over collections. The standard idiom to iterate over a collection is somewhat verbose:
    for (Iterator i = c.iterator(); i.hasNext(); ) {  // No ForUpdate
        String s = (String) i.next();
        ...
    }
The situation is made little better with the addition of generics:
    for (Iterator<String> i = c.iterator(); i.hasNext(); ) {
        String s = i.next();
        ...
    }
We propose a second form of the for loop specifically designed for iteration over collections and arrays. Traditionally this is done using a foreach keyword, but it seems unnecessary and counterproductive to add a keyword at this late date. Under the the syntax of this proposal, the above code could be replaced by this:
    for (String s : c) {
        ...
    }
Similarly, the following code could be used to calculate the sum of an int array.
    int sum = 0;
    for (int e : a)  // e is short for element; i would be confusing
        sum += e;
This proposal affects only the compiler; it demands no support from the VM. It does not require a new keyword and is fully compatible with all preexisting programs. The construct interacts harmoniously with existing elements of the language. For example, abrupt completion of an enhanced for statement is handled exactly like abrupt completion of any other for statement.

II. Syntax

The following description is not up to JLS standards, but should be good enough for present purposes. The new form of the for statement is governed by the following production:
 
   EnhancedForStatement:
        for ( Type Identifier : Expression )
            Statement
Expression must be an instance of a new interface called java.lang.Iterable, or an array. The interface java.util.Collection (and perhaps a few other interfaces or classes) will be retrofitted to extend (or implement) java.lang.Iterable:
package java.lang;

public class Iterable {
    /**
     * Returns an iterator over the elements in this collection.  There are no
     * guarantees concerning the order in which the elements are returned
     * (unless this collection is an instance of some class that provides a
     * guarantee).
     * 
     * @return an Iterator over the elements in this collection.
     */
    SimpleIterator iterator();
}
The interface java.util.Iterator will be retrofitted to implement a new interface java.lang.ReadOnlyIterator:
package java.lang;

public interface ReadOnlyIterator {
    /**
     * Returns true if the iteration has more elements. (In other
     * words, returns true if next would return an element
     * rather than throwing an exception.)
     *
     * @return true if the iterator has more elements.
     */
    boolean hasNext();

    /**
     * Returns the next element in the iteration.
     *
     * @return the next element in the iteration.
     * @exception NoSuchElementException iteration has no more elements.
     */
    Object next();
}
These new interfaces serve to prevent the dependency of the language on java.util that would otherwise result. Note that that they rely on covariant return types, which will be introduced as a part of support for generics (JSR-14).

II. Semantics

(Again, not up to JLS standards.) If Expression is an instance of java.util.Collection, the enhanced for statement is shorthand for this:
    for ( Iterator<T> $i = Expression.iterator(); $i.hasNext(); ) {
        Type Identifier = $i.next();
        Statement
    }
The identifier $i is used to indicate some synthetic variable name chosen by the compiler so as not to conflict with any other natural or synthetic variable name. The type T differs depending on whether Expression has a raw type or a parameterized type. If Expression has a raw type, T is Type; if Expression has a parameterized type, T is the the type parameter of Expression.

Note that the cast may generate a warning or error: if Expression has a raw type, then an unchecked assignment warning will be generated, correctly implying that the implicit cast may fail. If Expression has a parameterized type, the statement will generate a compilation error if the type parameter cannot be converted to Type by assignment conversion (JLS 5.2).

If Expression is an array, the enhanced for statement is shorthand for this:

{
    Type[] $a = Expression;

    L1: L2: ... Lm:

    for (int $i = 0; $i < $a.length; $i++) {
        Type Identifier = $a[ $i ] ;
        Statement
    }
}
The identifier $a is used to indicate some synthetic variable name chosen by the compiler so as not to conflict with any other natural or synthetic variable name. The possibly empty sequence of labels preceding the enhanced for loop is represented by L1: L2: ... Lm. This sequence is moved beyond the assignment to$a so that continue and break statements with labels will work properly.

The array form of the enhanced for statement will generate a compilation error if the array element type cannot be converted to Type by assignment conversion (JLS 5.2). Copyright 2000-2001 Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, California 94303 U.S.A. All rights reserved.