Java 为什么不是';这里不会抛出ConcurrentModificationException吗?

Java 为什么不是';这里不会抛出ConcurrentModificationException吗?,java,iterator,concurrentmodification,fail-fast,Java,Iterator,Concurrentmodification,Fail Fast,看看这段代码: ArrayList al = new ArrayList(); al.add("AA"); al.add("AB"); al.add("AC"); Iterator it = al.iterator(); while(it.hasNext()){ String s = (String)it.next(); if(s.equals("AB")){ al.remove(1); } } 由于ArrayList有fail fast iterator,而且很明显,给定的ArrayList

看看这段代码:

ArrayList al = new ArrayList();
al.add("AA");
al.add("AB");
al.add("AC");
Iterator it = al.iterator();
while(it.hasNext()){
String s = (String)it.next();
if(s.equals("AB")){
al.remove(1);
}
}
由于ArrayList有fail fast iterator,而且很明显,给定的ArrayList不是由固定大小的数组组成的(这会导致
remove()
方法不可用),因此上面的代码应该抛出
ConcurrentModificationException
,但确实没有

此外,如果我在循环中插入一条print语句(作为第一条语句),它将显示循环不会第三次迭代,并且会正常退出

我知道这听起来太愚蠢了,但我能想到的唯一错误原因是,元素的删除发生在迭代器遍历元素之后。但情况并非如此,因为
modificationCount
仍然通过删除进行修改,因此它必须抛出异常

正在做

while(it.hasNext()){
it.next();
al.remove(1);
}
但确实抛出ConcurrentModificationException


有什么见解吗?

发生这种情况是因为
hasNext()
方法没有检查
modCount

public boolean hasNext() {
    return cursor != size;
}
因此,在调用
remove(1)
之后,列表的大小将是2,就像光标一样,
hasNext()
将返回false。永远不会调用
next()
方法,也永远不会检查
modCount


如果在迭代之前向列表中添加第四个元素,将得到与第二个示例类似的异常。

仅在迭代器的
next()
调用期间检查并发修改,而不是在其
hasNext()
调用中检查并发修改,如中所述

草案明确规定,

失败快速迭代器在 尽力而为。因此,编写程序是错误的 这取决于这个异常的正确性:fail fast 迭代器的行为应该只用于检测bug


因此,在迭代过程中修改集合是一种错误的编程实践。

在我执行的所有执行过程中,都没有发现非常简单的流中的更改,这种尽力而为的基础是否如此糟糕?我相信还有其他类型的信号处理线程负责监听修改。从您告诉我的情况来看,如果我在使用迭代器进行遍历时尝试删除最后一个元素,就不会因为没有更多的next()调用而引发异常,不是吗?Bubletan的回答完全清楚了这一点。这真的不应该被称为“尽力而为的基础”:D谢谢!我喜欢准确、简短、健康的回答!谢谢。