我是靠谱客的博主 缥缈金鱼,这篇文章主要介绍Java中foreach循环两种实现原理,现在分享给大家,希望可以做个参考。

一、foreach循环Iterator模式
  • 首先我们看一个foreach循环的main方法
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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类的字节码文件反编译
复制代码
1
2
C:Program FilesJavajdk1.7.0_45bin>javap -verbose C:softwaredevelopworkpla ceggindextmpclassesggindexv2stockactionTest.class

我截取了反编译后输出的一段指令:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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数组类
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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命令反编译字节码文件
复制代码
1
2
C:Program FilesJavajdk1.7.0_45bin>javap -verbose C:softwaredevelopworkpla ceggindextmpclassesggindexv2stockactionTest.class
  • 编译的结果是:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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++)的引用模式来遍历数组

最后

以上就是缥缈金鱼最近收集整理的关于Java中foreach循环两种实现原理的全部内容,更多相关Java中foreach循环两种实现原理内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(80)

评论列表共有 0 条评论

立即
投稿
返回
顶部