转 java foreach实现原理

简介:

java.util.List实现了java.lang.Iterable接口.

jdk api文档中是这样描述Iterable接口的:实现这个接口允许对象成为 "foreach" 语句的目标。不过咋一看Iterable接口并没啥特别之处,只是定义了一个迭代器而已。

?
1
2
3
4
5
6
7
8
public  interface  Iterable<T> {  
     /** 
      * Returns an iterator over a set of elements of type T. 
      *  
      * @return an Iterator. 
      */  
     Iterator<T> iterator();  
}

究竟是如何实现foreach的呢,想想可能是编译器做了优化,就看了下最终编译成的字节码:

?
1
2
3
4
5
6
7
8
public  class  Iterable_eros {  
     List<String> strings;  
     public  void  display(){  
         for (String s : strings){  
             System.out.println(s);  
         }  
     }      
}

相应的字节码为:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public  void  display (){  
line0    : aload_0    
            getfield  java.util.List my.lang.Iterable_eros.strings  
            invokeinterface  java.util.Iterator java.util.List.iterator()  1  
            astore_2    
            goto   line30  
line13   : aload_2    
            invokeinterface  java.lang.Object java.util.Iterator.next()  1  
            checkcast  java.lang.String  
            astore_1    
line23   : getstatic  java.io.PrintStream java.lang.System.out  
            aload_1    
line27   : invokevirtual   void  java.io.PrintStream.println(java.lang.String)  
line30   : aload_2    
            invokeinterface   boolean  java.util.Iterator.hasNext()  1  
            ifne  line13  
line39   :  return

果然没猜错哈!可以看到,foreach语法最终被编译器转为了对Iterator.hasNext()和对Iterator.next()的调用。而作为使用者的我们, jdk并没用向我们暴露这些细节,我们甚至不需要知道Iterator的存在,认识到jdk的强大之处了吧。

为了证实自己的想法,又用Iterator写了个遍历List的方法查看了字节码,果然跟foreach的形式基本一样,当然这是后话~

?
1
2
3
4
5
6
7
8
9
10
11
public  void  display(){  
     for (String s : strings){  
         System.out.println(s);  
     }  
           
     Iterator<String> iterator = strings.iterator();  
     while (iterator.hasNext()){  
         String s = iterator.next();  
         System.out.println(s);  
     }  
}

用相应的字节码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public  void  display (){  
line0    : aload_0    
            getfield  java.util.List my.lang.Iterable_eros.strings  
            invokeinterface  java.util.Iterator java.util.List.iterator()  1  
            astore_2    
            goto   line30  
line13   : aload_2    
            invokeinterface  java.lang.Object java.util.Iterator.next()  1  
            checkcast  java.lang.String  
            astore_1    
line23   : getstatic  java.io.PrintStream java.lang.System.out  
            aload_1    
line27   : invokevirtual   void  java.io.PrintStream.println(java.lang.String)  
line30   : aload_2    
            invokeinterface   boolean  java.util.Iterator.hasNext()  1  
            ifne  line13  
            aload_0    
            getfield  java.util.List my.lang.Iterable_eros.strings  
            invokeinterface  java.util.Iterator java.util.List.iterator()  1  
            astore_1    
line49   :  goto   line69  
line52   : aload_1    
            invokeinterface  java.lang.Object java.util.Iterator.next()  1  
            checkcast  java.lang.String  
            astore_2    
line62   : getstatic  java.io.PrintStream java.lang.System.out  
            aload_2    
line66   : invokevirtual   void  java.io.PrintStream.println(java.lang.String)  
line69   : aload_1    
            invokeinterface   boolean  java.util.Iterator.hasNext()  1  
            ifne  line52  
line78   :  return

这边还发现一个比较有趣的现象:在取Iterator.next()之后并在把该值load进内容栈之前,编译器调用了checkcast  java.lang.String方法来进行类型安全检查,jdk应该是采用这个来检测并抛出ClassCastException的。

目录
相关文章
|
1月前
|
存储 算法 Java
滚雪球学Java(65):深入理解Java中的Map接口:实现原理剖析
【6月更文挑战第19天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
19 3
滚雪球学Java(65):深入理解Java中的Map接口:实现原理剖析
|
1月前
|
存储 缓存 算法
滚雪球学Java(62):HashSet的底层实现原理解析
【6月更文挑战第16天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
19 3
滚雪球学Java(62):HashSet的底层实现原理解析
|
1月前
|
存储 Java 测试技术
滚雪球学Java(61):从源码角度解读Java Set接口底层实现原理
【6月更文挑战第15天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
30 1
滚雪球学Java(61):从源码角度解读Java Set接口底层实现原理
|
1月前
|
安全 Java 程序员
Java基础18-一文搞懂Java多线程使用方式、实现原理以及常见面试题(二)
Java基础18-一文搞懂Java多线程使用方式、实现原理以及常见面试题(二)
36 4
|
1月前
|
存储 监控 算法
深入理解Java的垃圾回收机制(GC)实现原理
深入理解Java的垃圾回收机制(GC)实现原理
42 1
|
1月前
|
IDE Java 编译器
Java基础20-从IDE的实现原理聊起,谈谈那些年我们用过的Java命令(二)
Java基础20-从IDE的实现原理聊起,谈谈那些年我们用过的Java命令(二)
31 2
|
1月前
|
XML IDE Java
Java基础20-从IDE的实现原理聊起,谈谈那些年我们用过的Java命令(一)
Java基础20-从IDE的实现原理聊起,谈谈那些年我们用过的Java命令(一)
24 2
|
1月前
|
Java 程序员 调度
Java基础18-一文搞懂Java多线程使用方式、实现原理以及常见面试题(一)
Java基础18-一文搞懂Java多线程使用方式、实现原理以及常见面试题(一)
46 0
Java基础18-一文搞懂Java多线程使用方式、实现原理以及常见面试题(一)
|
1月前
|
Java 编译器
Java基础5-一文了解final关键字的特性、使用方法,以及实现原理(二)
Java基础5-一文了解final关键字的特性、使用方法,以及实现原理(二)
13 0
Java基础5-一文了解final关键字的特性、使用方法,以及实现原理(二)
|
19天前
|
Java
Java中多态的实现原理解析
Java中多态的实现原理解析