问题描述
String[] strs = new String[] { "1", "2", ... , "6" };
for (String s : strs) {
System.out.println(s);
}
这是一个关于Java的内部问题。
This is a question about java internals.
在上面的code样品,如何foreach循环弄清楚数组是多久?在阵列内部实际的物体或正在使用的东西像的sizeof
是无法访问的前端程序员?
In the above code sample, how does the foreach loop figure out how long the array is? Are arrays actually objects internally or is it using stuff like sizeof
that is inaccessible to front end programmers?
我有一种感觉,我只是缺少一些愚蠢的事,但我想这也可能是凉爽。 : - )
I have a feeling I'm just missing something stupid, but I figure it could also be cool. :-)
推荐答案
我整理了以下code:
I compiled the following code:
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);
}
}
}
这是拆解(的javap -c ArrayIterator
)字节code的迭代功能:
This is the disassembled (javap -c ArrayIterator
) bytecode for the iterating functions:
增强打印:
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
一个正常的循环:
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
正如你所看到的,在这两种情况下,编译器加载数组的长度( strs.length
)和循环反对。我们看到,增强的for-each循环,在一个阵列的情况下是循环对数组的长度(而不是在它使用一个Iterator对象的情况下)的语法糖。
As you can see, in both cases, the compiler is loading the arrays length (strs.length
) and looping against it. We see that the enhanced for-each loop, in the case of an Array is syntactic sugar for looping against the array's length (rather than in an Object's case where it uses an Iterator).
我已编辑正常的循环,使得它是惯用的要少得多,但它具有相同的字节code作为增强循环。对于所有意图和目的,正常的for循环版本是编译器生成什么时,它编译增强的for each循环。
I have edited the 'normal' for loop such that it is much less idiomatic, but that it has the same bytecode as the enhanced for loop. For all intents and purposes, the normal for loop version is what the compiler generates when it compiles the enhanced for each loop.
这篇关于怎样的Java知道如何迭代数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!