一、说明
- foreach 循环遍历的原理是通过迭代器 Iterator,不断获取 next 元素,所以使用 foreach,编译的时候编译器会自动将对 for 这个关键字的使用转化为对目标的迭代器的使用
- 我们常常认为,要想使用 foreach 循环遍历,就必须正确地实现 Iterable 接口,但是,你有没有想过,数组没有实现 Iterable 接口,为什么可以使用 foreach 语句循环遍历呢?这里我使用几个例子,以及进行Java反编译来说明数组这个特殊情况
二、集合使用foreach
- 首先,我们基于对照试验,使用实现 Iterable 接口的 Collection 集合(ArrayList)进行 foreach 使用
import java.util.ArrayList;
/**
*
* @author 吕泽江
* @version 创建日期: 2021-3-15 14:39:11
*/
public class TestCollection {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
arrayList.add(4);
arrayList.add(5);
for (Integer integer : arrayList) {
System.out.println(integer);
}
}
}
三、数组使用foreach
- 然后,我们使用没有实现 Iterable 接口的数组来进行 foreach 对比
/**
*
* @author 吕泽江
* @version 创建日期: 2021-3-15 14:42:28
*/
public class TestArray {
public static void main(String[] args) {
int[] arr = {
6,7,8,9,10};
for (int i : arr) {
System.out.println(i);
}
}
}
- 以上两个程序十分简单,可以看到输出结果均为预期结果,但是单单这样,我们还不至于探究数组与 foreach 的特殊关系
四、数组使用for
- 这里举例数组使用 for 的目的在于下述对于Java反编译的对照
/**
*
* @author 吕泽江
* @version 创建日期: 2021-3-15 14:45:42
*/
public class TestFor {
public static void main(String[] args) {
int[] arr = {
6,7,8,9,10};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
五、javap反编译程序
- 我们使用以下命令来对上述几个程序进行Java反编译处理
javac -encoding utf-8 TestCollection.java
javap -v TestCollection.class
javac -encoding utf-8 TestArray.java
javap -v TestArray.class
javac -encoding utf-8 TestFor.java
javap -v TestFor.class
5.1 TestCollection结果
Classfile /D:/workspace/Test/src/Test0315/TestCollection.class
Last modified 2021-3-15; size 852 bytes
MD5 checksum abb0ab7ce240eb4590733fa75e5448a5
Compiled from "TestCollection.java"
public class Test0315.TestCollection
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #13.#25 // java/lang/Object."<init>":()V
#2 = Class #26 // java/util/ArrayList
#3 = Methodref #2.#25 // java/util/ArrayList."<init>":()V
#4 = Methodref #9.#27 // java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
#5 = Methodref #2.#28 // java/util/ArrayList.add:(Ljava/lang/Object;)Z
#6 = Methodref #2.#29 // java/util/ArrayList.iterator:()Ljava/util/Iterator;
#7 = InterfaceMethodref #30.#31 // java/util/Iterator.hasNext:()Z
#8 = InterfaceMethodref #30.#32 // java/util/Iterator.next:()Ljava/lang/Object;
#9 = Class #33 // java/lang/Integer
#10 = Fieldref #<