Skompilowałem następujący kod:
public class ArrayIterator
{
public static void main(String[] argv)
{
String[] strs = new String[] { "1", "2", "3", "4", "5" };
enhancedPrint(strs);
normalPrint(strs);
}
public static void enhancedPrint(String[] strs)
{
for (String s : strs)
{
System.out.println(s);
}
}
public static void normalPrint(String[] strs)
{
String[] localArray = strs;
int len = localArray.length;
for (int i = 0; i < len; i++)
{
String s = localArray[i];
System.out.println(s);
}
}
}
to jest zdemontowany (javap -c ArrayIterator
) kodu bajtowego dla funkcji iteracji:
Udoskonalony druk:
public static void enhancedPrint(java.lang.String[]);
Code:
0: aload_0
1: astore_1
2: aload_1
3: arraylength
4: istore_2
5: iconst_0
6: istore_3
7: iload_3
8: iload_2
9: if_icmpge 31
12: aload_1
13: iload_3
14: aaload
15: astore 4
17: getstatic #10; //Field java/lang/System.out:Ljava/io/PrintStream;
20: aload 4
22: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: iinc 3, 1
28: goto 7
31: return
Normalny pętli for:
public static void normalPrint(java.lang.String[]);
Code:
0: aload_0
1: astore_1
2: aload_1
3: arraylength
4: istore_2
5: iconst_0
6: istore_3
7: iload_3
8: iload_2
9: if_icmpge 31
12: aload_1
13: iload_3
14: aaload
15: astore 4
17: getstatic #10; //Field java/lang/System.out:Ljava/io/PrintStream;
20: aload 4
22: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: iinc 3, 1
28: goto 7
31: return
Jak widać, w obu przypadkach, kompilator się ładuje długości tablic (strs.length
) i zapętlenie przeciwko niemu. Widzimy, że ulepszona pętla for-each, w przypadku tablicy to cukier syntaktyczny do pętli w stosunku do długości tablicy (a nie w przypadku obiektu, w którym używa on Iteratora).
I edycja „normalne” dla pętli tak, że jest znacznie mniej idiomatyczne, ale że jest to ten sam kod bajtowy jak zwiększona do pętli. Dla wszystkich celów i celów, normalna wersja pętli for jest tym, co kompilator generuje, gdy kompiluje ulepszony dla każdej pętli.
możliwy duplikat [Jak działa Java dla każdej pętli?] (Http://stackoverflow.com/questions/85190/how-does-the-java-for-each-loop-work) –
+1 ciekawy pytanie, a nie duplikat. –
Niezupełnie. Wiem, że to jest iterable, ale w jaki sposób iterator wie, kiedy przerwać iterację? – SapphireSun