Foreach与迭代器
Foreach与迭代器
Foreach语句可以用于数组和集合的遍历。之所以能够工作,是因为Java SE5引入了新的被称为Iterable的接口,该接口中包含一个能够产生Iterator的iterator()方法,并且Iterable接口被foreach用来在序列中移动。因此如果你创建了任何实现Iterable的类,都可以将它用于foreach语句中。 ——Java编程思想第4版 第11章 243页
1.任何实现了Iterable接口的类都可以用于foreach语句当中。
1 //: holding/IterableClass.java 2 // Anything Iterable works with foreach. 3 import java.util.*; 4 5 public class IterableClass implements Iterable<String> { 6 protected String[] words = ("And that is how " + 7 "we know the Earth to be banana-shaped.").split(" "); 8 public Iterator<String> iterator() { 9 return new Iterator<String>() { 10 private int index = 0; 11 public boolean hasNext() { 12 return index < words.length; 13 } 14 public String next() { return words[index++]; } 15 public void remove() { // Not implemented 16 throw new UnsupportedOperationException(); 17 } 18 }; 19 } 20 public static void main(String[] args) { 21 for(String s : new IterableClass()) 22 System.out.print(s + " "); 23 } 24 } /* Output: 25 And that is how we know the Earth to be banana-shaped. 26 *///:~
2.foreach实现原理:foreach语句最终被编译器转换成对iterator.next()和iterator.hashNext()方法的调用,也就是对Iterator的另一种封装形式而已。只是作为使用者,jdk屏蔽了这些实现细节。我们甚至不知道Iterator的存在。看编译生成的字节码:
Java代码:
1 import java.util.*; 2 public class Iterable_eros { 3 4 public static void main(String[] args) { 5 List<String> strings = null; 6 for(String s : strings){ 7 } 8 } 9 10 }
Javap -c 生成的字节码:
1 Compiled from "Iterable_eros.java" 2 public class Iterable_eros { 3 public Iterable_eros(); 4 Code: 5 0: aload_0 6 1: invokespecial #1 // Method java/lang/Object."<init>": 7 ()V 8 4: return 9 10 public static void main(java.lang.String[]); 11 Code: 12 0: aconst_null 13 1: astore_1 14 2: aload_1 15 3: invokeinterface #2, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator; 16 8: astore_2 17 9: aload_2 18 10: invokeinterface #3, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z 19 15: ifeq 31 20 18: aload_2 21 19: invokeinterface #4, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object; 22 24: checkcast #5 // class java/lang/String 23 27: astore_3 24 28: goto 9 25 31: return 26 }
加油