java中的foreach是如何实现的?
首先我们看一个foreach循环的main方法
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) {
List<String> list = Collections.emptyList();
for(String s:list) {
System.out.println("aaa..."+s);
}
System.out.println("end...");
}
}
使用java -verbose命令对Test类的字节码文件反编译
C:\Program Files\Java\jdk1.7.0_45\bin>javap -verbose C:\software\develop\workpla
ce\ggindex\tmp\classes\ggindex\v2\stock\action\Test.class
我截取了反编译后输出的一段指令:
0: invokestatic #16 // Method java/util/Collections.emtyList:()Ljava/util/List;
3: astore_1
4: aload_1
5: invokeinterface #22, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
10: astore_3
11: goto 46
14: aload_3
15: invokeinterface #28, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
20: checkcast #34 // class java/lang/String
23: astore_2
24: getstatic #36 // Field java/lang/System.out:Ljava/io/PrintStream;
27: new #42 // class java/lang/StringBuilder
30: dup
31: ldc #44 // String aaa...
33: invokespecial #46 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
36: aload_2
37: invokevirtual #49 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
40: invokevirtual #53 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
43: invokevirtual #57 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
46: aload_3
47: invokeinterface #62, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
52: ifne 14
55: getstatic #36 // Field java/lang/System.out:Ljava/io/PrintStream;
58: ldc #66 // String end...
60: invokevirtual #57 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
63: return
上面的指令都是jvm中的字节码指令,我们只需要看懂如下几行就可以,可以看到第五行的指令展示了java/util/List.iterator:()Ljava/util/Iterator;第15行的指令展示调用了java/util/Iterator.next:(),第47行指令展示调用了java/util/Iterator.hasNext:();这几行的输出就可以完全的说明foreach循环将对List数组的遍历转换成了Iterator目标迭代器的方式遍历。
List之所以能够使用foreach循环,List的所有实现类都是Collection接口的子类,而Collection又是Iterator接口的子类;List的实现类继承了一个AbstractList抽象类,这个抽象类完全实现了Iterator迭代器。
任何的一个集合,无论是JDK提供的还是自己实现的要想使用foreach循环必须实现Iterator迭代器。
只要是Collection的子类都可以使用foreach循环,前提是要实现了Iterator迭代器。
二、foreach循环引用模式
如下面的java数组类
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) {
String[] str = {"a","b"};
for(String s:str) {
System.out.println("aaa..."+s);
}
System.out.println("end...");
}
}
使用java -verbose命令反编译字节码文件
C:\Program Files\Java\jdk1.7.0_45\bin>javap -verbose C:\software\develop\workpla
ce\ggindex\tmp\classes\ggindex\v2\stock\action\Test.class
编译的结果是:
0: iconst_2
1: anewarray #16 // class java/lang/String
4: dup
5: iconst_0
6: ldc #18 // String a
8: aastore
9: dup
10: iconst_1
11: ldc #20 // String b
13: aastore
14: astore_1
15: aload_1
16: dup
17: astore 5
19: arraylength
20: istore 4
22: iconst_0
23: istore_3
24: goto 57
27: aload 5
29: iload_3
30: aaload
31: astore_2
32: getstatic #22 // Field java/lang/System.out:La/io/PrintStream;
35: new #28 // class java/lang/StringBuilde
38: dup
39: ldc #30 // String aaa...
41: invokespecial #32 // Method java/lang/StringBuild"<init>":(Ljava/lang/String;)V
44: aload_2
45: invokevirtual #35 // Method java/lang/StringBuildappend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
48: invokevirtual #39 // Method java/lang/StringBuildtoString:()Ljava/lang/String;
51: invokevirtual #43 // Method java/io/PrintStream.ptln:(Ljava/lang/String;)V
54: iinc 3, 1
57: iload_3
58: iload 4
60: if_icmplt 27
63: getstatic #22 // Field java/lang/System.out:La/io/PrintStream;
66: ldc #48 // String end...
68: invokevirtual #43 // Method java/io/PrintStream.ptln:(Ljava/lang/String;)V
71: return
通过上面的指令集我们可以推测foreach循环将普通的数组转换成了for(int i=0;i<4;i++)的引用模式来遍历数组。
版权声明:转载文章来自公开网络,版权归作者本人所有,推送文章除非无法确认,我们都会注明作者和来源。如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜。
【免责声明】本文部分系转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,如涉及作品内容、版权和其它问题,请在30日内与我们联系,我们会予以重改或删除相关文章,以保证您的权益!
Java开发高端课程免费试学
大咖讲师+项目实战全面提升你的职场竞争力
- 海量实战教程
- 1V1答疑解惑
- 行业动态分析
- 大神学习路径图
相关推荐
更多2024-04-08
2024-04-02
达内就业喜报
更多>Java开班时间
-
北京 丨 11月27日
火速抢座 -
上海 丨 11月27日
火速抢座 -
广州 丨 11月27日
火速抢座 -
兰州 丨 11月27日
火速抢座 -
杭州 丨 11月27日
火速抢座 -
南京 丨 11月27日
火速抢座 -
沈阳 丨 11月27日
火速抢座 -
大连 丨 11月27日
火速抢座 -
长春 丨 11月27日
火速抢座 -
哈尔滨 丨 11月27日
火速抢座 -
济南 丨 11月27日
火速抢座 -
青岛 丨 11月27日
火速抢座 -
烟台 丨 11月27日
火速抢座 -
西安 丨 11月27日
火速抢座 -
天津 丨 11月27日
火速抢座 -
石家庄 丨 11月27日
火速抢座 -
保定 丨 11月27日
火速抢座 -
郑州 丨 11月27日
火速抢座 -
合肥 丨 11月27日
火速抢座 -
太原 丨 11月27日
火速抢座 -
苏州 丨 11月27日
火速抢座 -
武汉 丨 11月27日
火速抢座 -
成都 丨 11月27日
火速抢座 -
重庆 丨 11月27日
火速抢座 -
厦门 丨 11月27日
火速抢座 -
福州 丨 11月27日
火速抢座 -
珠海 丨 11月27日
火速抢座 -
南宁 丨 11月27日
火速抢座 -
东莞 丨 11月27日
火速抢座 -
贵阳 丨 11月27日
火速抢座 -
昆明 丨 11月27日
火速抢座 -
洛阳 丨 11月27日
火速抢座 -
临沂 丨 11月27日
火速抢座 -
潍坊 丨 11月27日
火速抢座 -
运城 丨 11月27日
火速抢座 -
呼和浩特丨11月27日
火速抢座 -
长沙 丨 11月27日
火速抢座 -
南昌 丨 11月27日
火速抢座 -
宁波 丨 11月27日
火速抢座 -
深圳 丨 11月27日
火速抢座 -
大庆 丨 11月27日
火速抢座