日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java for each 的源_Java JDK1.5的新特性之for-each循环的底层原理

發(fā)布時(shí)間:2024/7/19 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java for each 的源_Java JDK1.5的新特性之for-each循环的底层原理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

今天給大家分享一下for-each循環(huán)的底層原理,故事還得從字節(jié)碼反匯編和反編譯說起...

首先看一下Java JDK1.5的新特性

泛型: ...

for-each. ...

自動(dòng)拆箱和裝箱功能 ...

枚舉: ...

可變參數(shù) ...

靜態(tài)導(dǎo)入 ...

線程并發(fā)庫

對(duì)于字節(jié)碼反匯編,可以使用 JDK 自帶的工具 javap

首先看一下 javap 有哪些指令以及用法

$ javap

用法: javap

其中, 可能的選項(xiàng)包括:

-help --help -? 輸出此用法消息

-version 版本信息

-v -verbose 輸出附加信息

-l 輸出行號(hào)和本地變量表

-public 僅顯示公共類和成員

-protected 顯示受保護(hù)的/公共類和成員

-package 顯示程序包/受保護(hù)的/公共類

和成員 (默認(rèn))

-p -private 顯示所有類和成員

-c 對(duì)代碼進(jìn)行反匯編

-s 輸出內(nèi)部類型簽名

-sysinfo 顯示正在處理的類的

系統(tǒng)信息 (路徑, 大小, 日期, MD5 散列)

-constants 顯示最終常量

-classpath 指定查找用戶類文件的位置

-cp 指定查找用戶類文件的位置

-bootclasspath 覆蓋引導(dǎo)類文件的位置

由此可見,在我們拿到字節(jié)碼文件之后,使用javap -c 字節(jié)碼文件位置,即可進(jìn)行反匯編

其實(shí) for-each 是 jdk 1.5 的語法糖,它可以迭代集合和數(shù)組

1.for-each 迭代集合

首先來看for-each 迭代集合

public static void main(String[] args) {

List a = new ArrayList<>();

a.add("1");

a.add("2");

a.add("3");

for (String temp : a) {

System.out.print(temp);

}

}

javap 反匯編這段代碼

$ javap -c ForeachTest.class

Compiled from "ForeachTest.java"

public class cn.ixan.design.ForeachTest {

public cn.ixan.design.ForeachTest();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

public static void main(java.lang.String[]);

Code:

0: new #2 // class java/util/ArrayList

3: dup

4: invokespecial #3 // Method java/util/ArrayList."":()V

7: astore_1

8: aload_1

9: ldc #4 // String 1

11: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z

16: pop

17: aload_1

18: ldc #6 // String 2

20: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z

25: pop

26: aload_1

27: ldc #7 // String 3

29: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z

34: pop

35: aload_1

36: invokeinterface #8, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;

41: astore_2

42: aload_2

43: invokeinterface #9, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z

48: ifeq 71

51: aload_2

52: invokeinterface #10, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;

57: checkcast #11 // class java/lang/String

60: astore_3

61: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;

64: aload_3

65: invokevirtual #13 // Method java/io/PrintStream.print:(Ljava/lang/String;)V

68: goto 42

71: return

}

由第 36 行,第 43 行,第 52 行可知,迭代集合使用到了 Iterator

然后使用 idea 查看字節(jié)碼文件,發(fā)現(xiàn) foreach 遍歷集合運(yùn)用迭代器

public static void main(String[] args) {

List a = new ArrayList();

a.add("1");

a.add("2");

a.add("3");

Iterator var2 = a.iterator();

while(var2.hasNext()) {

String temp = (String)var2.next();

System.out.print(temp);

}

}

2.for-each 迭代數(shù)組

我們知道集合繼承 Iterable 接口,使用使用 iterator 迭代集合,

那么數(shù)組沒有繼承 Iterable 接口,for-each 是如何迭代它呢?

首先來看 for-each 迭代數(shù)組

public static void main(String[] args) {

String[] arr = {"1","2"};

for(String e : arr){

System.out.println(e);

}

}

javap 反匯編這段代碼

$ javap -c ForeachTest.class

Compiled from "ForeachTest.java"

public class cn.ixan.design.ForeachTest {

public cn.ixan.design.ForeachTest();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

public static void main(java.lang.String[]);

Code:

0: iconst_2

1: anewarray #2 // class java/lang/String

4: dup

5: iconst_0

6: ldc #3 // String 1

8: aastore

9: dup

10: iconst_1

11: ldc #4 // String 2

13: aastore

14: astore_1

15: aload_1

16: astore_2

17: aload_2

18: arraylength

19: istore_3

20: iconst_0

21: istore 4

23: iload 4

25: iload_3

26: if_icmpge 49

29: aload_2

30: iload 4

32: aaload

33: astore 5

35: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;

38: aload 5

40: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

43: iinc 4, 1

46: goto 23

49: return

}

和迭代集合不同,沒有出現(xiàn) Iterator,說明沒有使用迭代器

第 18 行 arraylength,可能使用到了數(shù)組的 length 屬性

使用 idea 反編譯查看,發(fā)現(xiàn) for-each 遍歷數(shù)組是經(jīng)典 for 循環(huán)

public static void main(String[] args) {

String[] arr = new String[]{"1", "2"};

String[] var2 = arr;

int var3 = arr.length;

for(int var4 = 0; var4 < var3; ++var4) {

String e = var2[var4];

System.out.println(e);

}

}

總結(jié):? 1.for-each 迭代集合時(shí),使用的是迭代器迭代集合。

2.for-each 迭代數(shù)組時(shí),使用的是經(jīng)典for循環(huán)。

總結(jié)

以上是生活随笔為你收集整理的java for each 的源_Java JDK1.5的新特性之for-each循环的底层原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。