java常见小错误(二):Java迭代器iterator和for循环的区别
java常见错误系列文章
下一篇:java常见小错误(一):变量类型自动转换与强制转换
往期文章推荐:
java小技巧(三):JAVA 交集,差集,并集
java小技巧(二):进制转换
【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权);
本博客的内容来自于:java常见小错误(二):Java迭代器iterator和for循环的区别;
学习、合作与交流联系q384660495;
本博客的内容仅供学习与参考,并非营利;
文章目录
一、常见错误
在Iterator迭代器迭代过程或者foreach循环中,调用Collection的remove(obj)方法,要么会报错(并发修改的错误),要么行为不确定。
二、错误原因
foreach底层也是使用了iterator的方法。foreach反编译结果如下:
fail-fast,即快速失败,它是Java集合的一种错误检测机制。 当多个线程对集合(非fail-safe的集合类)进行结构上的改变的操作时,有可能会产生fail-fast机制,这个时候就会抛出ConcurrentModificationException(当方法检测到对象的并发修改,但不允许这种修改时就抛出该异常)。
同时需要注意的是,即使不是多线程环境,如果单线程违反了规则,同样也有可能会抛出改异常。
那这又和foreach循环有什么关系呢?
上文分析到了,foreach的底层是迭代器实现的,由debug发现,在迭代器中使用Iterator.next 会调用 Iterator.checkForComodification方法 ,而异常就是checkForComodification方法中抛出的。
我们直接看下checkForComodification方法的代码,看下抛出异常的原因:
-
modCount是ArrayList中的一个成员变量。它表示该集合实际被修改的次数。
-
expectedModCount 是 ArrayList中的一个内部类——Itr中的成员变量。expectedModCount表示这个迭代器期望该集合被修改的次数。其值是在ArrayList.iterator方法被调用的时候初始化的。只有通过迭代器对集合进行操作,该值才会改变。
-
Itr是一个Iterator的实现,使用ArrayList.iterator方法可以获取到的迭代器就是Itr类的实例。
他们之间关系:
由上图可知,迭代器开始遍历之前该迭代器的expectedModCount (期望集合修改次数ÿ