java foreach 语法是在jdk1.5时加入的新特性,主要是当作for语法的一个增强,那么它的底层到底是怎么实现的呢?因为面试时被问到,所以在这边做一个记录。

首先来看看foreach能够使用的类型是什么:

aaarticlea/png;base64,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" alt="" />

编译器报错原因写的很清楚了,要求:数组或java.lang.Iterable。

看下jdk源码对Iterable接口的声明:

/** Implementing this interface allows an object to be the target of
* the "foreach" statement.
* @since 1.5
*/
public interface Iterable<T> { /**
* Returns an iterator over a set of elements of type T.
*
* @return an Iterator.
*/
Iterator<T> iterator();
}

实现此接口,允许成为foreach语法的target。

那数组呢?数组没有实现为什么也可以用呢?

那是因为遍历数组时,会转换为对数组中的每一个元素的循环引用,相当于for语法循环遍历一样。

那么为什么是数组或者实现了这个接口,就能实现遍历呢?其实是因为编译器的原因,在编译中的语义分析过程中,有一个解除语法糖的操作,(语法糖是啥?可以理解成编译器为方便开发人员开发,会对特定代码做一些特殊处理,方便开发人员使用,除了foreach,java中还有泛型、装箱、拆箱、变长字符串等)。

  • 对于list编译器会调用Iterable接口的 iterator方法来循环遍历数组的元素,iterator方法中是调用Iterator接口的的 next()和hasNext()方法来做循环遍历。java中有一个叫做迭代器模式的设计模式,这个其实就是对迭代器模式的一个实现。
  • 对于数组,就是转化为对数组中的每一个元素的循环引用

java foreach 循环原理的更多相关文章

  1. Java语法糖1:可变长度参数以及foreach循环原理

    语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...

  2. java语法糖:(1)可变长度参数以及foreach循环原理

    语法糖 语法糖:是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这些语法做一些处理,开发者就可以直接方便地使用 ...

  3. for-each 循环原理

    for-each 循环原理1,for-each 是在java5 之后出现的.for是java 上的一个关键字,在jdk 找不到任何for的底层实现的.是因为for的底层实现被封装到了编译器中.所以通过 ...

  4. 可变长度参数以及foreach循环原理

    语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...

  5. Java for-each循环解惑

    Java for-each循环解惑 2014/04/24 | 分类: 技术之外 | 0 条评论 | 标签: JAVA 分享到:21 本文由 ImportNew - liqing 翻译自 javarev ...

  6. 反编译看java for-each循环

    java 1.5发行版引入的for-each循环.(引自<Effective Java>中文版第二版 第46条) 如以下对数组列表的for-each循环示例: public class F ...

  7. Java foreach循环

    foreach循环:增强性的for循环应用: 在for语句中,需要使用索引来进行操作具体的数组或集合内容操作:而foreach可以取消索引的操作细节: for ( 类型 变量 : 数组 | 集合 ) ...

  8. java foreach循环抛出异常java.util.ConcurrentModificationException

    代码如下: for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) { if (Integer.parseInt(i ...

  9. java foreach实现原理

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

随机推荐

  1. SharpGL学习笔记(十八) 解析3ds模型并显示

    笔者设想的3D仿真中的元件,是不可能都是“画”出来的.这样就玩复杂了,应该把任务分包出去,让善于制作模型的软件来制作三维模型,我们只需要解析并且显示它即可. 3dsmax制作三维模型的方便,快捷,专业 ...

  2. JAVA书写规范

    java程序书写规范 命名规范    1.一般概念        1.尽量使用完整的英文描述符        2.采用适用于相关领域的术语        3.采用大小写混合使名字可读        4 ...

  3. mongodb c#语法基础

    这里采用的是mongoDB官网推荐使用.net驱动: http://mongodb.github.io/mongo-csharp-driver/2.0/getting_started/quick_to ...

  4. windows下mongodb安装与使用

    首先安装mongodb 1.下载地址:http://www.mongodb.org/downloads 2.解压缩到自己想要安装的目录,比如d:\mongodb 3.创建文件夹d:\mongodb\d ...

  5. Javascript面向对象编程(三) --- 非构造函数的继承

    一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese = { nation:'中国' }; 还有一个对象,叫做&qu ...

  6. [ javascript css clip ] javascript css clip 的奇思妙想之文字拼接效果

      语法: clip : auto | rect ( number number number number ) 参数: auto : 对象无剪切 rect ( number number numbe ...

  7. 复杂对象的本地化(以Person为例)

    Person.h #import <Foundation/Foundation.h> @interface Person : NSObject <NSCoding> /// 姓 ...

  8. 题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。

    一.第一种写法 package com.pb.demo1; import java.util.Scanner; /** * 题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字. ...

  9. 【原/转】opencv的级联分类器训练与分类全程记录

    众所周知,opencv下有自带的供人脸识别以及行人检测的分类器,也就是说已经有现成的xml文件供你用.如果我们不做人脸识别或者行人检测,而是想做点其他的目标检测该怎么做呢?答案自然是自己训练一个特定的 ...

  10. 朝花夕拾-android 一个注册新用户时,多步填写用户资料的框架

    源码地址:http://git.oschina.net/zj2012zy/Android-Demo/tree/master/AndroidDemo/setpregister 效果如下: 基本思路: 1 ...