hasNext() 不检查 modCount,仅判断 cursor 是否小于 size;真正的 fail-fast 检查在 next() 中通过 checkForComodification() 执行,确保修改不一致时抛出 ConcurrentModificationException。

因为 hasNext() 本身不检查 modCount,它只判断游标是否越界。
hasNext() 的职责很轻量
它的核心逻辑就是比较当前 cursor 是否小于集合实际 size:
- 如果
cursor < size→ 返回true - 如果
cursor == size→ 返回false
这个判断不涉及结构一致性校验,也不读取元素内容,所以即使集合已被修改(modCount 已变),只要 cursor 还没超出当前 size,hasNext 就照常返回 true —— 它不负责“发现错误”,只负责“有没有下一个位置”。
检查被推迟到 next() 执行时
真正触发 fail-fast 的是 next() 方法,因为它要:
立即学习“Java免费学习笔记(深入)”;
- 先调用
checkForComodification() - 再取出并返回元素
- 最后推进 cursor
而 checkForComodification() 才会比对 modCount 和 expectedModCount。只有这时,不一致才会立刻暴露为 ConcurrentModificationException。
设计上兼顾性能与安全
把检查放在 next() 而非 hasNext(),有两点考虑:
- 避免冗余检查:一次 hasNext + 一次 next 是常见组合,合并检查到 next 更高效
- 语义更准确:hasNext 回答的是“位置是否存在”,next 才真正“消费”元素——出错理应发生在消费环节,而不是探路环节
这也解释了为什么删倒数第二个元素有时不报错
比如 list = [a,b,c],遍历到 b(cursor=1)时删掉 b,list 变成 [a,c],size 从 3→2;
- 下一次调用 hasNext():cursor=2,size=2 →
cursor == size→ 返回 false,循环结束 - next() 根本没被执行,所以没机会触发 checkForComodification()
但这不是“安全”,而是漏检——结果已错(c 被跳过),只是异常没抛出来。
fail-fast 不是万能锁,它只在迭代器真正尝试读取时才亮红灯。


















