Ist Java foreach Iterationsreihenfolge über Primitive genau definiert?
Frage
Beispielcode:
int a[] = new int[]{0, 1, 2, 3};
int result = 0;
for (int i : a)
result += i;
Ist die Schleife garantiert über a[0]
, a[1]
, a[2]
, a[3]
in dieser Reihenfolge zu durchlaufen? Ich glaube fest, die Antwort ist ja, aber dieser Seite scheint, um nicht eindeutig zu erklären.
Haben Sie eine feste Referenz?
Lösung
Nach der JLS, die verbesserte for
Anweisung ist Ihre for-Schleife entspricht
int[] array = a;
for (int index = 0; index < a.length; index++) {
int i = array[index];
result += i;
}
„wobei array
und index
sind Compiler generierten Kennungen, die von irgendwelchen anderen Kennungen eindeutig sind (Compiler erzeugt wird, oder auf andere Weise), die an dem Punkt in ihrem Umfang sind, wo die verbesserte for
Anweisung auftritt.“ (Leicht die Variablennamen hier paraphrasieren).
Also ja. Die Reihenfolge ist absolut garantiert
Andere Tipps
Siehe Abschnitt 14.14.2 der Java Language Specification , 3. Auflage .
Wenn die Art der Expression ist ein Subtyp von Iterable, dann lasse ich die Art sein, der Ausdruck Expression.iterator (). Die for-Anweisung verstärkt wird entsprechen einen Grund für Aussage die Form:
for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement }
Wo #i ist ein Compiler generierte Kennung, die von jedem unterscheidet andere Identifikatoren (Compiler generierte oder anders), die in ihrem Umfang sind (§6.3) an der Stelle, wo der erhöhte für Anweisung auftritt.
Es gibt in der JLS dass:
for ( VariableModifiersopt Type Identifier: Expression) Statement
entspricht
T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
VariableModifiersopt Type Identifier = a[i];
Statement
}
Ich habe nichts auf der Seite finden Sie verwiesen haben, die Out-of-Order-Iteration bedeuten würde. Können Sie das spezifische Angebot abgeben?
Auf jeden Fall finde ich, dass dieser Code:
public static void main( String args[] ) {
double a[] = new double[] { 0, 1, 2, 3 };
int result = 0;
for ( double i : a ) {
result += i;
}
dekompiliert zu altem Stil 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);
}
}
Natürlich, das ist nicht das gleiche wie eine Garantie, aber zumindest out-of-Order-Iteration über einen Array wäre sehr seltsam und würde gegen offensichtlich gesunden Menschenverstand Umsetzung zu gehen scheint.