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. DShow实现一个avi视频的播放(含有个人解释和注释)

    此项目为win32下的控制台C++代码(别忘记配置DShow库) // movie_test.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" ...

  2. 从web移动端布局到react native布局

    在web移动端通常会有这样的需求,实现上中下三栏布局(上下导航栏位置固定,中间部分内容超出可滚动),如下图所示: 实现方法如下: HTML结构: <div class='container'&g ...

  3. Azure SQL Database 时间点还原(Point in Time Restore)功能

      微软中国TechNet 7 Oct 2014 9:17 PM Comments 0 Likes 原文地址:http://blogs.technet.com/b/azuretw/archive/20 ...

  4. SharePoint 服务器端对象模型操作用户组(创建/添加/删除)

    摘要:几个操作SharePoint用户组的方法,已经测试通过,但是没有提升权限,如果没有权限的人操作,需要提升权限(提权代码附后).大家需要的话,可以参考下,写在这里也给自己留个备份~~ //创建用户 ...

  5. [ html canvas putImageData ] canvas绘图属性 putImageData 属性讲解

    <!DOCTYPE html> <html lang='zh-cn'> <head> <title>Insert you title</title ...

  6. iOS沙盒简单介绍

    先简单介绍一下什么是沙盒:你可以简单理解成为一个目录,这个目录的改动不会对操作系统造成任何损失.(这里也有一点点介绍) 看看苹果的沙盒目录: 再附一张苹果官方的图 一个iOS app操作都是在自己的沙 ...

  7. mybatis实战教程(mybatis in action),mybatis入门到精通(转)

    转自:http://www.yihaomen.com/article/java/302.htm (读者注:其实这个应该叫做很基础的入门一下下,如果你看过Hibernate了那这个就非常的简单) (再加 ...

  8. Block的使用及循环引用的解决

    Block是一个很好用的东西,这篇文章主要来介绍:1.什么是Block?2.Block的使用?3.Block的循环引用问题及解决. 1.什么是Block? 说这个问题之前,我先来说一下闭包(Closu ...

  9. android学习笔记 Service

    Service(服务): 长期后台运行的没有界面的组件 android应用什么地方需要用到服务? 天气预报:后台的连接服务器的逻辑,每隔一段时间获取最新的天气信息.股票显示:后台的连接服务器的逻辑,每 ...

  10. Linux线程学习(一)

    一.Linux进程与线程概述 进程与线程 为什么对于大多数合作性任务,多线程比多个独立的进程更优越呢?这是因为,线程共享相同的内存空间.不同的线程可以存取内存中的同一个变量.所以,程序中的所有线程都可 ...