1. 程式人生 > >java foreach的原理

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就是編譯器為我們生成的一個迭代器變數),這邊就是給這個迭代器賦值

核心實現就是以上幾行位元組碼,其餘的部分就是和接下來的迭代器遍歷有關了,有興趣的朋友可以看看.