这里以ArrayList为例
源代码
public class ArrayListDemo {
public static void main(String[] args) {
//list
List<Integer> list = new ArrayList<Integer>();
list.add(234);
list.add(121);
for(Integer dat:list){
System.out.println(dat);
}
}
}
使用javap -c 查看编译后的class文件
javap -c ArrayListDemo
输出
public static void main(java.lang.String[]);
Code:
0: new #2 // class java/util/ArrayList
3: dup
4: invokespecial #3 // Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: sipush 234
12: invokestatic #4 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
15: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
20: pop
21: aload_1
22: bipush 121
24: invokestatic #4 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
27: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
32: pop
33: aload_1
//调用的是iterator
34: invokeinterface #6, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
39: astore_2
40: aload_2
//调用的是iterator
41: invokeinterface #7, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
46: ifeq 69
49: aload_2
//调用的是iterator
50: invokeinterface #8, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
55: checkcast #9 // class java/lang/Integer
58: astore_3
59: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;
62: aload_3
63: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
66: goto 40
69: return
可以看到,foreach 循环内部实际是通过 Iterator 实现的.
上面的代码等同于
Iterator it = list.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
Iterator实现类Itr是ArrayList的一个内部类.modCount是ArrayList类t的一个私有属性,当对ArrayList进行添加或者删除元素时就会修改该值.ArrayList使用其来判断是否存在元素数量的变化.
在迭代过程中通过checkForComodification不断检测元素数量是否存在变化,如果有变化会抛出ConcurrentModificationException异常.
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
//创建内部类保存当前的modCount
int expectedModCount = modCount;
// prevent creating a synthetic constructor
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
//在迭代过程中比较expectedModCount 和 modCount是否不一致
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
综上所述,当在foreach循环中修改集合会出现的问题ConcurrentModificationException异常.