Is Java foreach iteration order over primitives precisely defined?

According to the JLS, The enhanced for statement, your for-loop is equivalent to

int[] array = a;
for (int index = 0; index < a.length; index++) {
    int i = array[index];
    result += i;
}

"where array and index 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." (slightly paraphrasing the variable names here).

So yes: the order is absolutely guaranteed.


It states in the JLS that:

for ( VariableModifiersopt Type Identifier: Expression) Statement

is equivalent to

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

See section 14.14.2 of the Java Language Specification, 3rd edition.

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.


I did not find anything in the page you've referenced that would imply out-of-order iteration. Can you post the specific quote?

In any case, I find that this code:

public static void main( String args[] ) {
    double a[] = new double[] { 0, 1, 2, 3 };
    int result = 0;
    for ( double i : a ) {
        result += i;
    }

decompiles to old-style looping:

 public static void main(String args[])
    {
        double a[] = {
            0.0D, 1.0D, 2D, 3D
        };
        int result = 0;
        double ad[];
        int k = (ad = a).length;
        for(int j = 0; j < k; j++)
        {
            double i = ad[j];
            result = (int)((double)result + i);
        }
    }

Of course, that's not the same as a guarantee, but at the very least out-of-order iteration over an array would be very weird and would seem to go against obvious common-sense implementation.