前言
本文从字节码层面看java 高级for循环的语法糖,用字节码分析,揭开高级for循环的面纱。
主要是调用 for(Object o : List) 或者 for(Object o: Object[] )
一、java for(Object o:Object[])
我们写一个简单的代码并 看下字节码:
//java 代码
public static void main(String[] args) {
Object [] numbers = new Object[]{};
for(Object i:numbers){
System.out.println(i);
}
}
//字节码
public static void main(java.lang.String[]);
Code:
//生成一个长度为0 的数组,放入 局部变量表第一个位置
0: iconst_0
1: anewarray #2 // class java/lang/Object
4: astore_1
// 将数组引用复制一份 放入局部变量表第二个位置,并计算数组长度放入局部变量表第三个位置
5: aload_1
6: astore_2
7: aload_2
8: arraylength
9: istore_3 //存放数组长度
//将0 加载到栈顶,这个代表索引,即我们常说的 i 并存入局部变量表第四个位置
10: iconst_0
11: istore 4
//加载 i 及数组长度 作比较
13: iload 4 //加载索引值 i
15: iload_3 //加载数组长度
16: if_icmpge 39 //如果i >= 数组长度跳转至39行,否则向下执行
19: aload_2 //加载数组到栈顶
20: iload 4 //加载索引到栈顶
22: aaload //加载数组中某个索引的值
23: astore 5 //数组中某个索引的对象存入局部变量表
25: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
28: aload 5
30: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
33: iinc 4, 1 //将索引值+1
36: goto 13 //跳转至13行继续执行
39: return
}
我们可以看到,数组的for循环for(Object o : Object[]),底层采用的是 for(int i,i < length;i++)的实现形式,前面的高级形式只是Java的语法糖
二、java for(Object o: List)
代码依然很简单
//java
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
for(Object o:list){
System.out.println(o);
}
}
//字节码
public static void main(java.lang.String[]);
Code:
//生成一个list,存入局部变量表第一个位置
0: new #2 // class java/util/ArrayList
3: dup
4: invokespecial #3 // Method java/util/ArrayList."<init>":()V
7: astore_1
// 获得list的 iterator 放入局部变量表的 第二个位置
8: aload_1
9: invokeinterface #4, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
14: astore_2
//加载 Iterator 并执行 hasNext,如果没有 则跳转至41行,有则继续往下执行
15: aload_2
16: invokeinterface #5, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
21: ifeq 41
//根据 Iterator.next 获取object 并输出,之后跳转至 15行继续循环
24: aload_2
25: invokeinterface #6, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
30: astore_3
31: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
34: aload_3
35: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
38: goto 15
41: return
我们可以看到,list的for循环for(Object o : List),底层采用的list的 iterator 的实现形式