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

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

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAawAAABkCAIAAABVZpOWAAAREUlEQVR4nO1dz48bRRae/8o+QIQ4zQVOwJJISDvjUcgoWbEhnQvsLsqy60hLFMNKIDFwtyVIOIC0UiCekIC1ewElsdECTgbsnQVbhJUjkIlE1Huo7ur3ql51tz3ttNv9ffoO456q6qrqqq9f/Xq95gMAAJQYa3lnAAAAIE9ABAEAKDUOJIJvO/DZZ59llT8AAICFYiEi+M4770AHAQAoBDIQQfvizz///O6770IHAQBYfmQjgn/evav48d49ahJmlMk02PXW1tbWvN2s0tvbWV9bW1vf2csqwZWEq5bU9Qwfx0KQdZsBiomMRVDpoO8wEkOoxkdhd6Ndz9k+efQgKmvQezvrJE3VI2lau16iwMndW84Vv11akFgxhU2PTBKZMf3sRdC+S5BWcpNxw/GAIIKA7ysR/OCDDy5IeP/99+MjGyJ46JFH1R/+zCK4ZrdGueGm0U9T5DIUQTlXKZITQGPNJ6MGMklktvQXYAlad8lABOd7QEBJsOb7/v7+viiC+/v78ZFFSzC1CEaNMlS29Z092q1soyAISK7t7XimJch00ttNEEH2T/JD54NmTscliVm3Y9fsQqpQVizJzuJRdO5IUCOEaAwaYYwsh6HN8kZPIKbszloyRVC6o0/0LShUvF0sGm5zVLWYIJVa5+BibX3nthQSKDSC4fClS5cMBbx06VJi5INZgsLb3ttltoVpFMS90BNF0EIaERQimLmS5Sw2C2LPNAtrRQmrZl1VVdu4kZiIEMa2panor5MOTv52WayuWmIi6Lij26pPPXqds6qlBI2kvF2jvUV/SyGBIiMQwbt37168eFEr4MWLF+/evZsYOTsRlC75cXN7tKlHDZaZOkY8C6lEkNlOrj7KbmeZF+s7e6J8m9ckcWVRgixJN3LUmFM3eBqRBc5fAEJFGOm7aoled92RXeeB4qZCLCN8jqp21o4R2FC+bKZBgGVDtDDyySefaBG8du1amsiLsASloMaIZM+fRwTnHQ5btzZyZdxOUFzD/mJyYL8JpCGkkFWhVK4aE8ev5k/2D7syjWxZg2gxNWq/WneUqtRQb3HkG108SFVbCRqJGTVOVVkMCRQYkQjeu3fvvffeU2bgvXv30kSmInjokUd/+9LOXCJIZobssFLzM3QiAxG0Oz+TZUujualii6DcM3T3tAZbYrJmFEkEhTojiQhhuJJEv1KLoPRErFqyLUHrjjGmtlwVDhGcs6qF0lsDX910dnbWLYvTnSxQMLAtMp9//vmFCxeuX7+eMvLBFkakt7jUsqlRIMZ0iKD+X/zqcOwcmZDB2FwJk24kd65r5gjPEcUshzAnaOVt1jnBFCJI03fVUpo5QRZXTUDG2MXujMxY1ebKmzxtzAfm61oD3SGBwsLcJ/jRRx+ljxyjdLOJoDXVbvcGx0qE3G+5cZm0RSZMMOwgTBR2PEdbF8fAwtDK6pnxFrBO1o7iGtzGJCKHoUmLA9sEEYzSd9VSytXhXR1tV7DqTENLmsKbvapFEaRZ2REnlO13jxkSKCoWcnY46xMjjtXCnLGgXGWS7KJrLOv0A2GJX+XJHPLCCFA2FEIEl3X2ZUG5yiTZRddYBumbAwIhtYWWIm5OESgR4E8QyAtMBB+wPabvDQ0EIIJAGRGIICQQgAgCAFByrFVPfwGCIFhaQgRBECw1IYIgCJaaEEEQBEtNiGCRWGmMB/601egtJHGv3xr5vu93mgtJP/bWw05suWrtacLkdndYaYwHo3HN6/GUg0L5/qTu9ZKSmtS9HokiwbqFSnPQ7puFak787jD+ilAVzcmg3a80JzrDQcSwfurd4A9aaZXmRMhnc+J3hxWv3xpFSYE2iyeCVhtd1AOutae6yVa8Ycf3aUNnfSm2ZZMGyvo5uT6pe71617c7kpnUIkWQlveBP9MEEUxZD0qM1MMS67zKBavSGA+iRyyLhVIl9zOVoV4k9S57o6QXQTtwrT1V+qtEMGyQw1pYuoo37CgRDyNWIILpWFQRXLS1os2KUHMnHS5SaTSrqppmaDvQ13ulOTFsiorXb40WJXBpmLJEC6ntGUWw3pVfPEYdiv0/ExE0KFqCdpqGrnGxdsAqprYEpTqECM5DiKBM4x1etTTCDpAi50FXd+ldGkthoUUuhAgaQ0WbzgHvaFzzeonDYft2giU4y5DZdUex/VBd1s8lHt9e/lbMTKcLEUzFFRHB8OKw4/v+aLx5iv2seT3+1g3NMSPW+WCQJYoU1QjeB9K2MN17lZnZChs3M0ykKacohcZ4oDPfGA9Id1JZ0knp0ZMRLIwolI4WJ0112fmksVihrG5vhAxEsB2OMd1vApXaYDTtNG2jj923Opcl+NdTseqmYJVdtASF/KQwKm0RpDU2aPeDJ2WFicYusARnZFFFMIJ63uGglXZX8pPN6EViZARraBEMRhb0vi5DSctNQrYb44GWoeZElCTxvlYiYc675ihbD7H1e0IO5phQ0wVMWV3WcyHz9PEZsCZYA01Uj9I976kj1trTTrNHY+msqmQF4yt8RipuVJ9zDYcTrTMtQ8bowRAvK5/TViOaP+GtPVrY6TR7bFKyO2SPzxx0QwQTWFQRdFiCPfknn4BjXVQaWYsWmUsE0wzlau0pnaE38kPUJ2FakFqCVdaFtLhMW41efDBX4qwXpaguYs1NWw3eLX1mBJn5FOZDDQGV5gqUHHSHVS5k9a5PZ1q1CDKRJQ80k+Gw8XA7zUi56EuRxlXvgFZ7at+FTRwnaZY4J0iFL7IE9QNK8ZIuM0srgnrYK4ngLJZgogja739DZLkJls4SVKNCFYtInkpKS4ArmCufbhGMqy6xkkmGzQzMIYKG0UdFkN46jQjSydyDL4ywSuPST+PSPS50TBCVjrcHoyXHw86eUT9gPMshgvb4jg8bg+tsOJwwJ6i3JtS7cW9aUXro/B0bDifplKgjNWJcVBrjwWjSCUVEDDbPcFiqLuu5DDukb9e7znzSkBVv2NJzgg4RtO/r6uSJw2FzufYAIkhmJ8m71toFFcziuUW/aolgZMpZI5JKc+KPpmIjiRuhwxKMZVFFkEAwUuxuEzvTb4pgNWl1mOVBD2REvbMGibrzd/iVqjWbI5SdzgmGGRh0JwNeIp91bDNYogimrC5H9oxiOvIZhWQD+aokgjZFEQyrOnY+wTByDzInGK41d5q9epe1Q9/3/e5Q12GiUcZqO1jK8P3ukK3hqNKxVT7n+xKW4Ewsngg+GCYu1ApRDrbBJU3nTzQVS0Kxkwe2Z8zmu+7Q3L3cGA/UURPLYqLyHSMoyv4SAwS7msmLwcTN74xFD9IYVCmmzfNhNoTDMGFJv7/zj9lXtEFNiKCTs56gOODrN802vZQr0SAIpidEsBgMx3owA0EwY0IEQRAsNSGCIAiWmhBBEARLzZxF8KHTN86eeOPDo8dv1g7frB3+8OjxsyfeeOj0jdzrBXwAFH3ngeADZp4i+NipT69sHdvzjo5effnOW+fvvHV+9OrLe6e2rmwde+zUp7lXTYGY6N5O9Ig3aPfT7LmpNMaddl9vo4vOrhrHYGZ3BRYdqJC8BmTrPDHxNM4ycKYjTGBWzE0EH/ZufLx1dPinkz+8ee6HN8+pvqr+Hr508uOtZw9513OvncJRS1XyCTx6oitp202trby2TFrh9l17P1CUoH3SK/AGOttetkKIYLb+xyCCuTA3ETx7/PXbz22M//4XRf/+ff/+ff3z9nMbZ4+/nnvtFIVp3Nul8VAvJm5HDLxpmRqnPXqO2dE0fiaMZfsB+k9ctAhm4uYSIpgLcxPBdm17/8yp7//2R8Vff7zz6/9+1D/3z5xq17Zzr52ikBiApiXo0qA0vu0o6+1JZ0T0NDq/FWhf6GZmUjfO54YZMJQ6GIxH/k4W28khgqCLuYngFxtP7J95/r8ve4q/9P/9y60v9c/9M89/sfFE7rVTFKZ0dMy+mkJ9/Wt/nNIINOyZ/dZoUm9OBu1hqzvpjCLvsHSoqz1u2Rmgh3ODj4GE0eUPFWXhQZaUItIR6Ywz8+oqnaGettrCvIESQXZWz3Liy1WSOPp1HLWmhjbJHnOOaeQTPAjzFMHhiyf+84ffKf70z6s//eua/jl88cTNzd/kXjuFY6JfL+Z2WJljppcn232Odg0wqYdOUmvtifIhSPWiFfV2lyXIRTD4l8NzQRYeZHnNuFOTvLpybzf91kg4gStagk7/sobfXyEbPAzLnuhpIodPA64ecxPBy7Vnvzm5OTh9VHH4wvHhC8f1z29Obl6uPZt77RSCaVzOmWsOgQKOXY7ypVtYn8oj/gi4u4HUw2Gv3xpNO13HV4oy9SBrjChdqdHCmi5npBUkWQQl/7KiZlnZkJ0hsY8oWSnn3gKLztxE8JXt174++vQ3v99QnH7Zm37Z0z+/Pvr0K9uv5V47xaLpV112ZRiYPGSLTII1Ya7qUkVjH9JjFoojCrMEq4aTQWF1ODMPspGOiH5eMxdBxxeQud82OxspRBAeNLJmbiJ4yLt+dXOzf+zI7RPP3D7xjOos6u/+sSNXNzexRWYmVrx+qz0JZ4smdcvBZ9Vwv0r36PmCh9coZamLBmIqfDXUH7SHiavDYa+O/OIJDkQz9SAr6gj382qJoGM4bPiddAyHLf+ybm/nJBvMHSTPnumPVqece9srOvPcLP34yWtXNze/2nrq1rHDt7aP3No+cuvY4a+2nrq6ufn4yWu5V01ByXe0RJ3E2NEmfgPItTXP9PoZfiiKuvbijkVNEdw0v+IWKGCUiL37OlMPsmxO0A7m8OpK1i6ihRFRBKOaT1j06MXlVoXp6jEvXQxxruqAB2TOx+Ye9m6c225c2di6ufHkzY0nr2xsndtuPOzh2NxspFNFwlfcHJ/BTdmFtLqRexGNa0780fgMH5MKkGxGYz7RXM9dMg+yGIquKuFAAVxS5u5Blpq09mdCwZUhRBBcOi6PB1lq2EIBV5UQQRAES02IIAiCpSZEEATBUhMiCIJgqQkRXBEaJ9vUNkC6u0V0vEq23R5o01khfP8l1Z7kviXTcoHLSYjgilAUwaoSFHqWzjhaFx7nKIkI8m2MpLoggiUmRHAVyI73qhMLzYk6VxtcDNz2hd4GqSO/LEQwWy5IBCv8KCE9N52VRxZ4dikiIYIrQm0JUkE0trZRn/jBp0JKI4LGqdvgIvdhBREsJyGCK0JzOBzZeswdAMekzkVw7tHf8jtAdXh2Cf1xubyZ0nJJ3kzpxW8vf2e4Vs29VYBpCBFcEZID+cwzlW3iaXuw1hjWGhmL4NI6QI13b+X0Zur0taU9XBmHtWEJFo8QwVVgOAQ2ZvqnA2KCSa4Npq1GhgsjS+0A1S2C1BK0HPlRd14cgVNut2MIsCiECK4IzeGwNAWmSGcGM10dXmoHqDPNCcoiaGsoRHAlCBFcEVIRrHf9wK8qXwJWIe1PBlfDfYIZDIeX2AFqrT2NXx0WvJky5bX9pNKbDlsOH/rgkhMiuCIM5SBahYjMGb43kIwuI0XIck5wWR2g8jD27IHkzdS94GMlGH05AAsjxSJEcBXo8j2l1y4DB87WwqWxnDJ/BlbUAeqylQtcBCGCYAZcVQeouZcLfACECIIH4qo6QF2ecoGLJkQQBMFSEyIIgmCpuWbunwUAACgTIIIAAJQaEEEAAEoNiCAAAKUGRBAAgFIDIggAQKkBEQQAoNSACAIAUGpABAEAKDUgggAAlBoQQQAASg2IIAAApQZEEACAUgMiCABAqQERBACg1IAIAgBQakAEAQAoNSCCAACUGhBBAABKDYggAAClBkQQAIBSAyIIAECpAREEAKDUgAgCAFBqQAQBACg1IIIAAJQa/welqTtOBEDJzwAAAABJRU5ErkJggg==" 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学习笔记(十五) 纹理映射

    纹理映射非常实用,在游戏场景中已经无所不在了. 一个较少的多边形构成的模形,配合好的纹理贴图进行映射,可以得到逼真的效果.游戏中的天空,地面,墙面,和植物都是纹理贴图进行映射的. 例如最终幻想8的男女 ...

  2. [性能] Bean拷贝工具类性能比较

    Bean拷贝工具类性能比较 引言 几年前做过一个项目,接入新的api接口.为了和api实现解耦,决定将api返回的实体类在本地也建一个.这样做有两个好处 可以在api变更字段的时候保持应用稳定性 可以 ...

  3. js和html5实现画板

    html5新添了一个重要又强大的标签元素<canvas>,该标签真有彻底替换掉flash的尽头,现在很多网页游戏就是用<canvas>完成的,下面代码就是用该标签制作的一个画板 ...

  4. CSS 属性 - 伪类和伪元素的区别

    伪类和伪元素皆独立于文档结构.它们获取元素的途径也不是基于id.class.属性这些基础的元素特征,而是在处于特殊状态的元素(伪类),或者是元素中特别的内容(伪元素).区别总结如下: ①写法不一样: ...

  5. Force.com微信企业号开发系列(一) - 启用二次验证

    微信于9月份推出企业号后引起了业界不小的反响,许多企业都在思索企业号将如何影响企业的运营,从本文开始,我将详细阐述微信企业号开发的相关知识,而本文将着重介绍如何实现更高安全机制的二次验证. 申请企业体 ...

  6. iOS菜单滚动联动内容区域功能实现

    平时开发APP中关于此功能还是比较经常碰到,本实例借用三个开源的插件,并对其中一个进行修改调整实现出想要的效果:本文重点介绍修改的内容跟三个插件的运用,这三个插件还可以各自扩展到其它项目的运用: 效果 ...

  7. iOS 内存管理(一)之基础知识介绍

    1,什么是引用计数 所有OC对象都有一个计数器,叫做引用计数,引用计数就是目前有几个对象在使用该对象(持有该对象的引用): 2,什么是对象所有权 A对象拥有B对象的引用,A对象拥有B对象的所有权: 3 ...

  8. OC字符串的一些常用的函数。

    )//获取字符串长度 NSUInteger len= str.length; () //通过指定索引返回对应的字符 unichar ch =[str characterAtIndex:]; ()//通 ...

  9. PAT 01-2

    #include<stdio.h> #include<stdlib.h> int main() { int k; int *data; int i; int ThisSum, ...

  10. 导出excel乱码问题

    今天遇到一个问题,在用C#做导出excel的时候,出现excel乱码问题.百度了下. 发现问题如下: 非中文字符编码问题. 解决方法: 把输出的excel格式设置成UTF-8即可. 更改代码: Res ...