我是靠谱客的博主 安详宝贝,最近开发中收集的这篇文章主要介绍java中foreach_Java中foreach的实现原理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1、foreach循环遍历对象

foreach循环遍历对象的时候底层是使用迭代器进行迭代的,即该对象必须直接或者间接的实现了Iterable接口,一般以able结尾代表某种能力,实现了iterable代表给予了实现类迭代的能力。

我们先写一个List集合然后使用 javac 类名.java 对该.java文件进行编译成类名.class字节码文件然后使用 javap -verbose 类名.class指令进行反编译查看一下字节码指令,或者如果用的是Intellij idea的话,里面内置了Fernflower decompiler,直接打开.class文件会直接显示反编译后的代码(记得在查看class文件之前要先执行一下它的java文件)。这里我们使用两种方式都来试验一下。

下面是我写的一个简单的List集合的对象

1 importjava.util.Collections;2 importjava.util.List;3

4 public classTest {5 public static voidmain(String[] args) {6 List list =Collections.emptyList();7 for(inta : list){8 System.out.println(a);9 }10 }11

12 }

直接使用指令反编译

这里我是找到我的Test.java文件的地址,拖到桌面上然后执行

javac Test.java

在桌面上生成生成Test.class文件,然后执行

javap -verbose Test.class

就会显示反编译后的信息,这里我截取了main方法中的一段

Code:

stack=2, locals=4, args_size=1

0: invokestatic #2 //Method java/util/Collections.emptyList:()Ljava/util/List;

3: astore_14: aload_15: invokeinterface #3, 1 //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;

10: astore_211: aload_212: invokeinterface #4, 1 //InterfaceMethod java/util/Iterator.hasNext:()Z

17: ifeq 43

20: aload_221: invokeinterface #5, 1 //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;

26: checkcast #6 //class java/lang/Integer

29: invokevirtual #7 //Method java/lang/Integer.intValue:()I

32: istore_333: getstatic #8 //Field java/lang/System.out:Ljava/io/PrintStream;

36: iload_337: invokevirtual #9 //Method java/io/PrintStream.println:(I)V

40: goto 11

43: return

根据第5行和第13行判断出使用了迭代器进行了迭代。

使用Intellij idea直接查看

使用Intellij idea直接查看Test.class文件的话会显示如下,感觉挺方便的

1 //

2 //Source code recreated from a .class file by IntelliJ IDEA3 //(powered by Fernflower decompiler)4 //5

6 packagesdu.edu.Test;7

8 importjava.util.Collections;9 importjava.util.Iterator;10 importjava.util.List;11

12 public classTest {13 publicTest() {14 }15

16 public static voidmain(String[] args) {17 List list =Collections.emptyList();18 Iterator var2 =list.iterator();19

20 while(var2.hasNext()) {21 int a =(Integer)var2.next();22 System.out.println(a);23 }24

25 }26 }

可以看到直接把foreach转换成新建了List的迭代器进行迭代。

2、foreach循环遍历数组

foreach循环遍历数组的时候将其转型成为对每一个数组元素的循环引用

还是按照上面同样的方法来进行查看

Test.java代码如下

1 public classTest {2 public static voidmain(String[] args) {3 String[] strs= new String[3];4 for(String str : strs){5 System.out.println(str);6 }7 }

8 }

执行上面的指令后反编译信息如下:

Code:

stack=2, locals=6, args_size=1

0: iconst_31: anewarray #2 //class java/lang/String

4: astore_15: aload_16: astore_27: aload_28: arraylength9: istore_310: iconst_011: istore 4

13: iload 4

15: iload_316: if_icmpge 39

19: aload_220: iload 4

22: aaload23: 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/String;)V

33: iinc 4, 1

36: goto 13

39: return

对字节码指令不熟悉的我看不出来上面什么意思......

运用Intellij idea查看Test.class文件后如下图所示

//

//Source code recreated from a .class file by IntelliJ IDEA//(powered by Fernflower decompiler)//

packagesdu.edu.Test;public classTest {publicTest() {

}public static voidmain(String[] args) {

String[] strs= new String[3];

String[] var2=strs;int var3 =strs.length;for(int var4 = 0; var4 < var3; ++var4) {

String str=var2[var4];

System.out.println(str);

}

}

}

根据Intellij idea来查看还是比较清晰的,foreach转变成对每一个数组元素的

参考文章:

最后

以上就是安详宝贝为你收集整理的java中foreach_Java中foreach的实现原理的全部内容,希望文章能够帮你解决java中foreach_Java中foreach的实现原理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部