foreach语法相信大家都不会陌生吧,接下来我们进行详细分析,提出几个问题?
什么情况下才能使用foreach语法进行遍历?
先看代码:
public class T01 implements Iterable<Integer>{
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
@Override
public boolean hasNext() {
return true;
}
@Override
public Integer next() {
return 1;
}
@Override
public void remove() {
}
};
}
public static void main(String[] args) {
T01 t01 = new T01();
for (Integer integer : t01) {
System.out.println(integer);
}
}
}
当然程序会无限打印,为了演示我并没有优化。看出来了吧,要使用foreach语法,必须实现接口Iterable;
foreach怎么使用iterator呢?
看代码:
public class T01{
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
for (Integer each : list) {
}
}
}
我们进行javap编译:
public static void main(java.lang.String[]);
Code:
0: new #16 // class java/util/ArrayList
3: dup
4: invokespecial #18 // Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1 //ArrayList实例入栈
9: invokeinterface #19, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
14: astore_3 //构造遍历器,并保存到局部变量 3中,
15: goto 28 //一下都是遍历跳转到28
18: aload_3
19: invokeinterface #25, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
24: checkcast #31 // class java/lang/Integer
27: astore_2
28: aload_3
29: invokeinterface #33, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
34: ifne 18 //栈顶数不为0跳转到18,也就是next方法。为什么不是判断true。因为虚拟机考虑到指令太多会造成没必要的复杂度,对boolean只提供有限的支持,在Java中涉及到boolean类型值的运算,在编译之后都使用int数据类型来代替。
37: return
看到这里应该明白了吧,其实就是对foreach语法编译期优化,运用Iterator进行遍历。