String[] strs = new String[] { "1", "2", ... , "6" };
for (String s : strs) {
System.out.println(s);
}
这是关于java internals的问题。
在上面的代码示例中,foreach循环如何计算出数组的长度?数组实际上是内部对象,还是使用前端程序员无法访问的sizeof
之类的东西?
我有一种感觉,我只是错过了一些愚蠢的东西,但我认为它也可能很酷。 : - )
答案 0 :(得分: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);
}
}
}
这是迭代函数的反汇编(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
正常的循环:
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循环,在Array的情况下是用于循环数组长度的语法糖(而不是在Object使用Iterator的情况下)。
我已经编辑了'normal'for循环,因此它不那么惯用,但是它与增强的for循环具有相同的字节码。对于所有意图和目的,循环版本的正常版本是编译器在为每个循环编译增强函数时生成的。
答案 1 :(得分:3)
是的,有类似于C ++ sizeof
运算符的东西 - 它是length实例变量(它给出了数组中元素的数量,而不是大小以字节为单位。)length
字段始终是数组的公共成员,因此Java程序员可以访问它。
是的,数组是objects,而不仅仅是内部。
(更广泛地说,for
循环语法的工作方式与org.life.java链接到的question中的描述相同;但这并不是您所要求的。)
答案 2 :(得分:1)
是的,数组是具有“长度”字段的对象。 Java语言规范:http://java.sun.com/docs/books/jls/third_edition/html/arrays.html#64347