プリミティブ以上のJava foreachの繰り返し順序は正確に定義されていますか?
質問
例コード:
int a[] = new int[]{0, 1, 2, 3};
int result = 0;
for (int i : a)
result += i;
ループは、その順序でa[0]
、a[1]
、a[2]
、a[3]
渡って繰り返し処理することが保証されていますか?私は強く答えはイエスが、このページであると信じ>明確に順序を述べるないようです。
固体の参照をお持ちですか?
解決
JLS rel="noreferrer">のfor声明には、あなたのためのループ
と等価ですint[] array = a;
for (int index = 0; index < a.length; index++) {
int i = array[index];
result += i;
}
「ここでarray
とindex
を向上<=>ステートメントが発生した時点でスコープ内にある任意の他の識別子(コンパイラ生成またはその他)は異なるコンパイラ生成識別子です。」 (少しここで変数名を言い換え)。
そうです:。順序が絶対的に保証されている。
他のヒント
Java言語仕様のセクション14.14.2を参照してください。 、第3版でます。
Expressionの型は、サブタイプである場合 反復処理可能で、その後、私はのタイプも聞かせて 表現Expression.iterator()。 for文で強化 の文の基本と同等 フォーム:
for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement }
#Iは、コンパイラが生成している場合は 任意区別される識別子 他の識別子(コンパイラが生成しました その他)(§6.3)の範囲内にあること 以下のための強化ポイントで ステートメントが発生します。
これは<のhref = "http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.14.2" のrel = "nofollowをnoreferrer" で述べています>そののJLSます:
for ( VariableModifiersopt Type Identifier: Expression) Statement
タグに相当します
T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
VariableModifiersopt Type Identifier = a[i];
Statement
}
私は、アウトオブオーダーの繰り返しを含意するでしょう、あなたが参照したページには何も見つかりませんでした。あなたは、特定の引用を投稿することができますか?
いずれにせよ、私はこのコードを見つけます:
をpublic static void main( String args[] ) {
double a[] = new double[] { 0, 1, 2, 3 };
int result = 0;
for ( double i : a ) {
result += i;
}
古いスタイルのループを逆コンパイルます:
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);
}
}
もちろん、それは保証と同じではありませんが、配列にわたって非常に少なくとも、アウト・オブ・オーダーの繰り返しは非常に奇妙なことだろうと明らかに常識的な実装に反するように思われます。