为什么不能在foreach中执行remove/add操作
| 本文总阅读量次测试代码:
1 | public static void main(String[] args) { |
如果运行上述代码,会抛出ConcurrentModificationException异常。
为什么会报错呢?
javap -c
命令查看编译后代码,了解下上述代码运行过程:
上图代码A处,可以看到foreach循环是使用的是Iterator迭代器,代码B处使用Iterator迭代器中的next方法获取集合中的值,代码C处使用list.remove()删除集合中的值。
Itr迭代器类的next方法:
1 | public E next() { |
list.remove方法代码:
1 | public synchronized boolean removeElement(Object obj) { |
首先next方法中,首先判断modCount的值,如果modCount的值和expectedModCount值不一致,就会抛出ConcurrentModificationException异常。而恰恰remove方法中就修改了modCount的值,而未修改expectedModCount的值,从而导致我们的测试代码抛出ConcurrentModificationException异常。
抛错的源头找到了,可是为什么会出现这种问题呢?
我们看下导致抛出源头的两个参数modCount和expectedModCount。modCount是类Vector的成员变量,主要记录Vector的修改次数;expectedModCount是内部迭代器类Itr的成员变量,初始化时等于modCount。我们使用foreach去remove集合内的值时,调用的是Vector类的remove方法,不是迭代器Itr的remove方法,所以只会修改modCount的值,而不更新expectedModCount的值。所以在测试代码中报错是因为在第一次删除后,modCount值+1,而expectedModCount的值未变化,所以在迭代器再次调用next方法获取集合内的值时就会抛出ConcurrentModificationException异常。
- 本文链接: http://blog.programer.group/faq/2018-07-30-foreach/
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!