java -- 增强for循环

是什么

增强for循环是JDK1.5后引入java的一种语法,其目的主要是方便遍历集合中的元素。

干什么

对于集合的遍历,我们先看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
Collection<String> c = new ArrayList<String>();
c.add("I");
c.add("love");
c.add("java");

for(String str:c){
System.out.println(str);
}

输出为:
I
love
java

这种方法相对于以前的将集合转数组,抑或是通过迭代器遍历,都显得更为简单直接。

什么时候可以用

在JDK文档中指出,凡是实现了iterable接口的子类对象都可以使用增强for循环。

注意

如果我们在增强for中,同时修改了遍历集合,就会抛出ConcurrentModificationException异常。这里为深入了解其中机制,我们有必要知道增强for在遍历时,到底做了什么?

利用反编译工具procyon.jar,我们对上述代码进行了反编译,过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
rqsir@rqsir-TM1604:~/IdeaProjects/EnhancedForLoop/out/production/EnhancedForLoop$ java -jar /opt/procyon.jar -b EnhancedForLoopTest.class
public class EnhancedForLoopTest {
public void EnhancedForLoopTest() {
invokespecial:Object(Object::<init>, this:EnhancedForLoopTest)
}

public static void main(java.lang.String[] args) {
c : Collection<String>
var_2_29 : Iterator<String>
str : String

c = initobject:ArrayList<String>[expected:Collection<String>](ArrayList<E>::<init>)
invokeinterface:boolean(Collection<String>::add, c:Collection<String>, ldc:String("I"))
invokeinterface:boolean(Collection<String>::add, c:Collection<String>, ldc:String("love"))
invokeinterface:boolean(Collection<String>::add, c:Collection<String>, ldc:String("java"))
var_2_29 = invokeinterface:Iterator<String>(Collection<String>::iterator, c:Collection<String>)

while (invokeinterface:boolean(Iterator<E>::hasNext, var_2_29:Iterator<String>)) {
str = checkcast:String(java.lang.String.class, invokeinterface:String(Iterator<String>::next, var_2_29:Iterator<String>))
invokevirtual:void(PrintStream::println, getstatic:PrintStream(System::out), str:String)
}
}

从上面的反编译结果中,我们不能发现,所谓的增强for循环,实际上是由编译器在底层帮我们装换成了iterator的while遍历。既然调用了iterator,那么并发修改就需要上心了,详情可以参考java – 迭代器并发修改异常