• java foreach实现原理


       在平时Java程序中,应用比较多的就是对Collection集合类的foreach遍历,foreach之所以能工作,是因为这些集合类都实现了Iterable接口,该接口中定义了Iterator迭代器的

    产生方法,并且foreach就是通过Iterable接口在序列中进行移动。

     Iterable接口API:

    package java.lang;
    
    import java.util.Iterator;
    
    public interface Iterable
    {
    
        public abstract Iterator iterator();
    }

    该接口中定义了产生Iterator迭代器的方法;

    package java.util;
    
    
    public interface Iterator
    {
    
        public abstract boolean hasNext();
    
        public abstract Object next();
    
        public abstract void remove();
    }

    那么为什么实现了Iterable接口就支持foreach操作了呢?

    我们写段foreach小程序看看字节码是怎么样的吧.

    package test;
    
    import java.util.List;
    
    /**
     * Created by vino on 2016/5/6.
     */
    public class TestForeach {
        List<Integer> integers;
        public void testForeach(){
            for(Integer i : integers){
    
            }
        }
    }

    其中TestForeach方法的详细字节码如下:

     public void testForeach();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=3, args_size=1
             0: aload_0
             1: getfield      #2                  // Field integers:Ljava/util/List;
             4: invokeinterface #3,  1            // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
             9: astore_1
            10: aload_1
            11: invokeinterface #4,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
            16: ifeq          32
            19: aload_1
            20: invokeinterface #5,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
            25: checkcast     #6                  // class java/lang/Integer
            28: astore_2
            29: goto          10
            32: return
          LineNumberTable:
            line 11: 0
            line 13: 29
            line 14: 32
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
               29       0     2     i   Ljava/lang/Integer;
                0      33     0  this   Ltest/TestForeach;
    }

     我们重点看红色部分,我来简单解释一下这段字节码的作用:

    0:加载this到操作栈

    1:获取字段integers

    4:调用integers的接口方法interator

    9:将返回的迭代器赋给本地变量?(我们看到在最下面的本地变量区的Slot列,有0和2,但是没有1.事实上,1就是编译器为我们生成的一个迭代器变量),这边就是给这个迭代器赋值

    核心实现就是以上几行字节码,其余的部分就是和接下来的迭代器遍历有关了,有兴趣的朋友可以看看.

  • 相关阅读:
    zap日志库
    Go Logger库基本使用
    golang中的MySQL增删改查
    golang链接mysql
    文件上傳
    參數綁定:
    gin獲取path參數
    gin獲取form提交的表單數據
    獲取query string
    返回json
  • 原文地址:https://www.cnblogs.com/vinozly/p/5465454.html
Copyright © 2020-2023  润新知