Sap*_*Sun 7 java arrays foreach
String[] strs = new String[] { "1", "2", ... , "6" };
for (String s : strs) {
System.out.println(s);
}
Run Code Online (Sandbox Code Playgroud)
这是关于java internals的问题.
在上面的代码示例中,foreach循环如何计算出数组的长度?数组实际上是内部对象还是使用sizeof前端程序员无法访问的东西?
我有一种感觉,我只是错过了一些愚蠢的东西,但我觉得它也很酷.:-)
Ree*_*ore 11
我编译了以下代码:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是javap -c ArrayIterator迭代函数的反汇编()字节码:
增强的印刷品:
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
Run Code Online (Sandbox Code Playgroud)
循环的正常:
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
Run Code Online (Sandbox Code Playgroud)
如您所见,在这两种情况下,编译器都会加载数组length(strs.length)并对其进行循环.我们看到增强的for-each循环,在Array的情况下是用于循环数组长度的语法糖(而不是在Object使用Iterator的情况下).
我已经编辑了'normal'for循环,因此它不那么惯用,但是它与增强的for循环具有相同的字节码.对于所有意图和目的,循环版本的常规是编译器在为每个循环编译增强时生成的.