java forEach实现原理
2016-09-17 13:31
204 查看
java.util.List实现了java.lang.Iterable接口.
jdk api文档中是这样描述Iterable接口的:实现这个接口允许对象成为 "foreach" 语句的目标。不过咋一看Iterable接口并没啥特别之处,只是定义了一个迭代器而已。
<span style="font-size:12px;">public interface Iterable<T> {
/**
* Returns an iterator over a set of elements of type T.
*
* @return an Iterator.
*/
Iterator<T> iterator();
} </span>
究竟是如何实现foreach的呢,想想可能是编译器做了优化,就看了下最终编译成的字节码
public class Iterable_eros {
List<String> strings;
public void display(){
for(String s : strings){
System.out.println(s);
}
}
} 相应的字节码为:
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.next()的调用。而作为使用者的我们, jdk并没用向我们暴露这些细节,我们甚至不需要知道Iterator的存在,认识到jdk的强大之处了吧。
为了证实自己的想法,用Iterator写了个遍历List的方法查看了字节码,果然跟foreach的形式基本一样,当然这是后话~
这边还发现一个比较有趣的现象:在取Iterator.next()之后并在把该值load进内容栈之前,编译器调用了checkcast java.lang.String方法来进行类型安全检查,jdk应该是采用这个来检测并抛出ClassCastException的。
顺着上面的思路猜想了下数组越界异常应该也是通过在字节码中添加在访问数组前的下标检查实现的,不过写了个例子看了下,并没用类似于checkindex java.lang.Array之类的语句,哈哈,留着以后再想吧~
jdk api文档中是这样描述Iterable接口的:实现这个接口允许对象成为 "foreach" 语句的目标。不过咋一看Iterable接口并没啥特别之处,只是定义了一个迭代器而已。
<span style="font-size:12px;">public interface Iterable<T> {
/**
* Returns an iterator over a set of elements of type T.
*
* @return an Iterator.
*/
Iterator<T> iterator();
} </span>
究竟是如何实现foreach的呢,想想可能是编译器做了优化,就看了下最终编译成的字节码
public class Iterable_eros {
List<String> strings;
public void display(){
for(String s : strings){
System.out.println(s);
}
}
} 相应的字节码为:
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.next()的调用。而作为使用者的我们, jdk并没用向我们暴露这些细节,我们甚至不需要知道Iterator的存在,认识到jdk的强大之处了吧。
为了证实自己的想法,用Iterator写了个遍历List的方法查看了字节码,果然跟foreach的形式基本一样,当然这是后话~
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); } }
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的。
顺着上面的思路猜想了下数组越界异常应该也是通过在字节码中添加在访问数组前的下标检查实现的,不过写了个例子看了下,并没用类似于checkindex java.lang.Array之类的语句,哈哈,留着以后再想吧~
相关文章推荐
- java forEach实现原理
- 使用临界段实现优化的进程间同步对象-原理和实现
- 基于Socket的聊天室实现原理
- P2P 之 UDP穿透NAT的原理与实现-转自CSDN[hBifTs]
- C# 2.0 中Iterators的改进与实现原理浅析
- 利用泛解析实现二级域名原理以及程序
- .NET 1.1中预编译ASP.NET页面实现原理浅析 [1] 自动预编译机制浅析
- 基于IMD的包过滤防火墙原理与实现
- RunDll32 的使用方法与实现原理
- CLR 中匿名函数的实现原理浅析
- 使用临界段原理实现优化的进程间同步对象-原理和实现
- 自解压的jar实现原理
- C# 2.0 中Iterators的改进与实现原理浅析
- .NET 1.1中预编译ASP.NET页面实现原理浅析 [1] 自动预编译机制浅析
- gzip原理与实现
- 即时战略游戏中寻径(Path-finding)算法的原理及实现技术
- 动态数据窗创建原理及实现
- 深入分析基于VCL派生的ActiveX控件的实现原理及应用
- 求:Microsoft .Net Passport实现原理
- 游戏外挂的原理及实现