Java中foreach的实现原理

1、foreach循环遍历对象

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

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

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

import java.util.Collections;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<Integer> list = Collections.emptyList();
        for(int a : list){
            System.out.println(a);
        }
    }

}

直接使用指令反编译

这里我是找到我的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_1
         4: aload_1
         5: invokeinterface #3,  1            // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
        10: astore_2
        11: aload_2
        12: invokeinterface #4,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
        17: ifeq          43
        20: aload_2
        21: 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_3
        33: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
        36: iload_3
        37: invokevirtual #9                  // Method java/io/PrintStream.println:(I)V
        40: goto          11
        43: return

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

使用Intellij idea直接查看

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

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

package sdu.edu.Test;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class Test {
    public Test() {
    }

    public static void main(String[] args) {
        List<Integer> list = Collections.emptyList();
        Iterator var2 = list.iterator();

        while(var2.hasNext()) {
            int a = (Integer)var2.next();
            System.out.println(a);
        }

    }
}

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

2、foreach循环遍历数组

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

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

Test.java代码如下

public class Test {
    public static void main(String[] args) {
        String[] strs=  new String[3];
        for(String str : strs){
            System.out.println(str);
        }
    }
}

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

Code:
      stack=2, locals=6, args_size=1
         0: iconst_3
         1: anewarray     #2                  // class java/lang/String
         4: astore_1
         5: aload_1
         6: astore_2
         7: aload_2
         8: arraylength
         9: istore_3
        10: iconst_0
        11: istore        4
        13: iload         4
        15: iload_3
        16: if_icmpge     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/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)
//

package sdu.edu.Test;

public class Test {
    public Test() {
    }

    public static void main(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转变成对每一个数组元素的

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值