java中使用迭代器iterator引发运行时异常的源码分析

话不多说,直接上代码

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
while (iterator.hasNext()) {
	if ("b".equals(iterator.next())) {
		list.add("d");
	}
}

当使用以上方法时,会抛出 ConcurrentModificationException 并发修改异常的情况

接下来分析为何会出现以上问题

image-20200828094853947

根据错误信息可以了解到,最终错误其实是由ArrayList的checkForComodification方法导致的,因此可以进入到源码进行查看

image-20200828094949270

可以看到,当 modCount != expectedModCount 时,系统就会抛出ConcurrentModificationException异常

接下来去查看modCount和expectedModCount两个变量是从哪里来的

在ArrayList中没有找到modCount,因此去查看ArrayList的父类AbstractList

image-20200828095919147

成功找到modCount

image-20200828100017275

因为是使用ArrayList的iterator()方法得到迭代器,所以去查看ArrayList的iterator()方法的实现

image-20200828100352591

发现创建了Itr对象并直接返回,在Itr类代码中,可以看到

image-20200828100434924

也就是说,每一次通过iterator()方法得到迭代器时,都会将modCount变量值赋值给expectedModCount

同时,在Itr内部类的next()方法中可以看到

image-20200828101057153

也就是说,每次调用迭代器的next()方法,都会去进行一次判断,一旦发现modCount变量和expectedModCount变量不一致,就会抛出异常

接下来直接跟进ArrayList的add()方法的实现代码

image-20200828100804745

每一次执行add方法时,modCount都会自行+1

由此可以发现,因为每次在使用add方法时,modCount都会 +1,而expectedModCount却未能发生改变,所以在使用next()方法时,会发生异常

while (iterator.hasNext()) {
     // 调用next方法时,会先去调用checkForComodification方法进行检测,一旦add方法被调用,
     // modCount变量会发生改变,从而抛出异常
	if ("b".equals(iterator.next())) {
		list.add("d");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值