循环List删除元素抛ConcurrentModificationException异常原因分析

来源:互联网 发布:sql查询字段包含分号 编辑:程序博客网 时间:2024/05/16 11:42

使用for(Object obj:list)进行循环ArrayList时,如果循环删除list中的元素则会抛出 ConcurrentModificationException异常,如下图:


通过分析错误堆栈我们可以发现使用 for(Object obj:list) 进行循环时,实际上是调用List迭代器(iterator)的next方法进行循环(AbstractList类中的Itr内部类的next方法):


这时,next方法的第一行会对ArryList做校验,如果校验不通过,则抛出ConcurrentModificationException异常

checkForComodification方法:

该方法实际上是对modCount和expectedModCount变量进行比较,如果不同,则抛出异常。
这里涉及到两个变量:
modCount:AbstractList类成员变量。记录List结构变化的次数,每次改变list结构时(add,remove,trimToSize等)都会加1

expectedModCount:Itr(AbstractList类的迭代器)类成员变量,初始时和modCount相等:

每次调用迭代器的remove方法会对expectedModCount重新赋值modCount相同:

了解这两个变量后我们就会发现,for循环中调用的remove方法是ArrayList的remove方法会对modCount变量加1,但expectedModCount变量并未改变。这样,在第二次循环时调用迭代器的next方法就会校验出错。

所以,如果需要对list进行循环删除时要使用迭代器,并调用迭代器的remove方法。




0 0