为什么不在此处抛出 ConcurrentModificationException?
Why isn't ConcurrentModificationException being thrown here?
看看这段代码:
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 有快速失败迭代器,很明显,给定的 ArrayList 不是由固定大小的数组组成的(这将呈现 remove()
方法不可用 ),上面的代码应该抛出 ConcurrentModificationException
但是,是的,它没有。
此外,如果我在循环中插入一条打印语句(作为第一条语句),它表明循环没有进行第三次迭代并且正常退出。
我知道这听起来太愚蠢了,但我能想到 错误 的唯一原因是元素的删除发生在之后 ] 该元素已被迭代器遍历。但事实并非如此,因为 modificationCount
仍会通过删除进行修改,因此它必须抛出异常。
正在做
while(it.hasNext()){
it.next();
al.remove(1);
}
虽然会抛出 ConcurrentModificationException。
有什么见解吗?
这是因为 hasNext()
方法没有检查 modCount
:
public boolean hasNext() {
return cursor != size;
}
因此,在调用remove(1)
后,列表的大小将与光标一样为2,而hasNext()
将return为false。 next()
方法永远不会被调用并且 modCount
永远不会被检查。
如果您在迭代之前将第四个元素添加到列表中,您将得到与第二个示例类似的异常。
并发修改的检查仅在迭代器的 next()
调用期间发生,而不是在其 hasNext()
调用内发生,如 中所述。
java documentation for ArrayList
明确规定,
Fail-fast iterators throw ConcurrentModificationException on a
best-effort basis. Therefore, it would be wrong to write a program
that depended on this exception for its correctness: the fail-fast
behavior of iterators should be used only to detect bugs.
因此,在迭代时修改集合是一种错误的编程习惯。
看看这段代码:
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 有快速失败迭代器,很明显,给定的 ArrayList 不是由固定大小的数组组成的(这将呈现 remove()
方法不可用 ),上面的代码应该抛出 ConcurrentModificationException
但是,是的,它没有。
此外,如果我在循环中插入一条打印语句(作为第一条语句),它表明循环没有进行第三次迭代并且正常退出。
我知道这听起来太愚蠢了,但我能想到 错误 的唯一原因是元素的删除发生在之后 ] 该元素已被迭代器遍历。但事实并非如此,因为 modificationCount
仍会通过删除进行修改,因此它必须抛出异常。
正在做
while(it.hasNext()){
it.next();
al.remove(1);
}
虽然会抛出 ConcurrentModificationException。
有什么见解吗?
这是因为 hasNext()
方法没有检查 modCount
:
public boolean hasNext() {
return cursor != size;
}
因此,在调用remove(1)
后,列表的大小将与光标一样为2,而hasNext()
将return为false。 next()
方法永远不会被调用并且 modCount
永远不会被检查。
如果您在迭代之前将第四个元素添加到列表中,您将得到与第二个示例类似的异常。
并发修改的检查仅在迭代器的 next()
调用期间发生,而不是在其 hasNext()
调用内发生,如
java documentation for ArrayList
明确规定,
Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
因此,在迭代时修改集合是一种错误的编程习惯。