foreach语法是java se5引入的,用于遍历数组或者java.lang.Iterable的实例对象.
来看看下面的代码:
int[] array = { 1, 2, 3 };
for (int num : array) {
array = null;
System.out.print(num);
}
输出结果是123.
可能和很多朋友心中的答案不一样,这个问题很难从源码方面进行分析,以下是这几句话的反汇编结果:
0: iconst_3
1: newarray int
3: dup
4: iconst_0
5: iconst_1
6: iastore
7: dup
8: iconst_1
9: iconst_2
10: iastore
11: dup
12: iconst_2
13: iconst_3
14: iastore
15: astore_1
16: aload_1
17: dup
18: astore 5
20: arraylength
21: istore 4
23: iconst_0
24: istore_3
25: goto 45
28: aload 5
30: iload_3
31: iaload
32: istore_2
33: aconst_null
34: astore_1
35: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
38: iload_2
39: invokevirtual #22 // Method java/io/PrintStream.print:(I)V
42: iinc 3, 1
45: iload_3
46: iload 4
48: if_icmplt 28
51: return
0-15的这些指令完成了int[] array = { 1, 2, 3 };
之后的指令完成了整个遍历过程,大致过程包括:
1.将array的值(指向数组的引用,即地址)赋值给第5个局部变量(局部变量从0开始编号,且这个遍历源码中不可见)
2.将array的长度赋值给第4个局部变量
3.将0赋值给第3个局部变量
4.每次循环会检查第3个局部变量是不是小于第4个局部变量,如果小于则执行我们在foreach中的代码.
下面的代码用以模拟上述步骤:
int[] array = { 1, 2, 3 };
int[] v5 = array;
int v4 = array.length;
for (int v3 = 0; v3 < v4; v3++) {
int num = v5[v3];
array = null;
System.out.print(num);
}
对于Iterable的实现类来说,foreach在底层的实现是利用Iterator的hasNext()和next()方法来完成,在此不做详细讨论.