Java中foreach循環(huán)的實現(xiàn)原理

1沾凄、背景知識介紹

java foreach 語法是在jdk1.5時加入的新特性喜滨,主要是當(dāng)作for語法的一個增強(qiáng),那么它的底層到底是怎么實現(xiàn)的呢冶匹?因為面試時被問到伴鳖,所以在這邊做一個記錄。

2 什么是foreach循環(huán)徙硅?

For-each語法內(nèi)部榜聂,對collection是用nested iteratoration來實現(xiàn)的,對數(shù)組是用下標(biāo)遍歷來實現(xiàn)嗓蘑。

Java 5 及以上的編譯器隱藏了基于iteration和下標(biāo)遍歷的內(nèi)部實現(xiàn)须肆。(注意,這里說的是“Java編譯器”或Java語言對其實現(xiàn)做了隱藏桩皿,而不是某段Java代碼對其實現(xiàn)做了隱藏豌汇,也就是說,我們在任何一段JDK的Java代碼中都找不到這里被隱藏的實現(xiàn)泄隔。這里的實現(xiàn)拒贱,隱藏在了Java 編譯器中,查看一段For-each的Java代碼編譯成的字節(jié)碼佛嬉,從中揣測它到底是怎么實現(xiàn)的了)

下面對“For-each”和“其對等的iteration/index實現(xiàn)”的對比再簡潔明了不過了逻澳。


Example - Adding all elements of an array

Here is a loop written as both afor-eachloop and a basicforloop.

double[] ar = {1.2, 3.0, 0.8};

int sum = 0;

for (double d : ar) {? // d gets successively each value in ar.

? ? sum += d;

}

And here is the same loop using the basicfor. It requires an extra iteration variable.

double[] ar = {1.2, 3.0, 0.8};

int sum = 0;

for (int i = 0; i < ar.length; i++) {? // i indexes each element successively.

? ? sum += ar[i];

}

Where thefor-eachis appropriate

一定要注意For-each不是萬能的,下面的場合是不適宜使用For-each的

Altho the enhancedforloop can make code much clearer, it can't be used in some common situations.

使用For-each時對collection或數(shù)組中的元素不能做賦值操作

Only access. Elements can not be assigned to, eg, not to increment each element in a collection.

同時只能遍歷一個collection或數(shù)組暖呕,不能同時遍歷多余一個collection或數(shù)組

Only single structure. It's not possible to traverse two structures at once, eg, to compare two arrays.

遍歷過程中斜做,collection或數(shù)組中同時只有一個元素可見,即只有“當(dāng)前遍歷到的元素”可見湾揽,而前一個或后一個元素是不可見的瓤逼。

Only single element. Use only for single element access, eg, not to compare successive elements.

只能正向遍歷笼吟,不能反向遍歷(相比之下,C++ STL中還有reverse_iterator, rbegin(), rend()之類的東西霸旗,可以反向遍歷)

Only forward. It's possible to iterate only forward by single steps.

如果要兼容Java 5之前的Java版本贷帮,就不能使用For-each

At least Java 5. Don't use it if you need compatibility with versions before Java 5.

三. 代碼分析

通過javap反編譯可以知道實現(xiàn)了Iterable接口

在編譯的時候編譯器會自動將對for這個關(guān)鍵字的使用轉(zhuǎn)化為對目標(biāo)的迭代器的使用,這就是foreach循環(huán)的原理诱告。進(jìn)而撵枢,我們再得出兩個結(jié)論:

1、ArrayList之所以能使用foreach循環(huán)遍歷蔬啡,是因為ArrayList所有的List都是Collection的子接口,而Collection是Iterable的子接口镀虐,ArrayList的父類AbstractList正確地實現(xiàn)了Iterable接口的iterator方法箱蟆。之前我自己寫的ArrayList用foreach循環(huán)直接報空指針異常是因為我自己寫的ArrayList并沒有實現(xiàn)Iterable接口

2、任何一個集合刮便,無論是JDK提供的還是自己寫的空猜,只要想使用foreach循環(huán)遍歷,就必須正確地實現(xiàn)Iterable接口

數(shù)組呢恨旱?

上面的講完了辈毯,好理解,但是不知道大家有沒有疑問搜贤,至少我是有一個疑問的:數(shù)組并沒有實現(xiàn)Iterable接口啊谆沃,為什么數(shù)組也可以用foreach循環(huán)遍歷呢?因為Java將對于數(shù)組的foreach循環(huán)轉(zhuǎn)換為對于這個數(shù)組每一個的循環(huán)引用仪芒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末唁影,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子掂名,更是在濱河造成了極大的恐慌据沈,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饺蔑,死亡現(xiàn)場離奇詭異锌介,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)猾警,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門孔祸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人发皿,你說我怎么就攤上這事融击。” “怎么了雳窟?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵尊浪,是天一觀的道長匣屡。 經(jīng)常有香客問我,道長拇涤,這世上最難降的妖魔是什么捣作? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮鹅士,結(jié)果婚禮上券躁,老公的妹妹穿的比我還像新娘。我一直安慰自己掉盅,他們只是感情好也拜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著趾痘,像睡著了一般慢哈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上永票,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天卵贱,我揣著相機(jī)與錄音,去河邊找鬼侣集。 笑死键俱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的世分。 我是一名探鬼主播编振,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼臭埋!你這毒婦竟也來了党觅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤斋泄,失蹤者是張志新(化名)和其女友劉穎杯瞻,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炫掐,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡魁莉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了募胃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旗唁。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖痹束,靈堂內(nèi)的尸體忽然破棺而出检疫,到底是詐尸還是另有隱情,我是刑警寧澤祷嘶,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布屎媳,位于F島的核電站夺溢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏烛谊。R本人自食惡果不足惜风响,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丹禀。 院中可真熱鬧状勤,春花似錦、人聲如沸双泪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽焙矛。三九已至葫盼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間薄扁,已是汗流浹背剪返。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工废累, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留邓梅,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓邑滨,卻偏偏與公主長得像日缨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子掖看,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 在一個方法內(nèi)部定義的變量都存儲在棧中匣距,當(dāng)這個函數(shù)運(yùn)行結(jié)束后,其對應(yīng)的棧就會被回收哎壳,此時毅待,在其方法體中定義的變量將不...
    Y了個J閱讀 4,417評論 1 14
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法归榕,內(nèi)部類的語法尸红,繼承相關(guān)的語法,異常的語法刹泄,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • 從相識到相知特石,那么多年盅蝗,曾經(jīng)我也吃過很多苦,但世間所有美好的安排姆蘸,都總是先苦后甜墩莫。 苦的是最初的生活芙委,甜的是夫妻間...
    瞧那一家子閱讀 451評論 0 0
  • 進(jìn)地鐵閘的那一刻才發(fā)現(xiàn)深圳通余額不足,可出門一毛錢也沒有帶贼穆,銀行卡倒是帶了题山,現(xiàn)在都是手機(jī)支付,出門都不帶現(xiàn)金故痊,...
    吳槿瑄閱讀 287評論 0 3
  • 文/薛松 日前顶瞳,國家發(fā)展改革委等八部門聯(lián)合發(fā)布《關(guān)于在一定期限內(nèi)適當(dāng)限制特定嚴(yán)重失信人乘坐火車 推動社會信用體系建...
    寒巖不冷閱讀 388評論 0 4