美国上市公司,专注Java培训21年

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答疑解惑
  • 行业动态分析
  • 大神学习路径图

相关推荐

更多
  • Java编程工具用哪个最好
    Java编程工具用哪个最好
    Java编程工具用哪个最好?Java编程工具的选择取决于个人的偏好、项目需求和开发环境。以下是一些常用的Java编程工具: 详情>>

    2024-04-03

  • 好用的Java编写软件
    好用的Java编写软件
    Java是一种广泛使用的编程语言,因其跨平台、安全性和稳定性而受到许多开发者的喜爱。Java被用于开发各种类型的软件,从桌面应用程序到企业级服务器端应用程序。以下是一些常见的、用Java编写的软件示例: 详情>>

    2024-04-02

  • Java测试工具有哪些?
    Java测试工具有哪些?
    Java测试工具有哪些?Java测试工具有很多,可以用于不同的测试阶段和目的,包括单元测试、集成测试、性能测试等。以下是一些流行的Java测试工具: 详情>>

    2024-04-02

  • Java有哪些课程?
    Java有哪些课程?
    Java是一种功能丰富且易于学习的编程语言,适用于多种不同的应用领域。目前,许多机构和在线平台都提供了丰富的Java相关课程,课程内容涵盖了Java的基础知识、高级特性以及实际应用等方面。以下是一些Java课程的示例: 详情>>

    2024-03-14

  • Java开班时间

    收起