为什么这段代码不能输入ConcurrentModificationException
?它在修改Collection
的同时迭代遍历它,而不使用Iterator.remove()
方法,它的意思是the only safe way of removing。为什么此代码不会引发ConcurrentModificationException?
List<String> strings = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (String string : strings)
if ("B".equals(string))
strings.remove("B");
System.out.println(strings);
我得到同样的结果,如果我有一个LinkedList
更换ArrayList
。但是,如果我将列表更改为("A", "B", "C", "D)
或只是("A", "B")
,我会按预期得到异常。到底是怎么回事?如果这是相关的,我正在使用jdk1.8.0_25
。
编辑
我发现下面的链接
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4902078
相关的部分是
天真的解决方案是商品化检查添加到hasNext在AbstractList中,但这样做会使检查的成本增加一倍。 事实证明,仅在最后一次迭代中进行测试就足够了,这样做几乎不会增加成本。换句话说, 当前实现hasNext的:
public boolean hasNext() { return nextIndex() < size; }
由该实施方案替换:
public boolean hasNext() { if (cursor != size()) return true; checkForComodification(); return false; }
这种变化将不能进行,因为太阳内部监管机构拒绝了。正式的裁决表明,该变更“具有 ”表明对现有代码具有显着兼容性影响 的潜力。“ (其中“兼容性影响”是修复具有 与 ConcurrentModificationException的更换无声的不当行为的潜力。)
因为'ConcurrentModificationException'被套上一个“尽力而为”的基础上 –
可能重复:预期时java.util.ConcurrentModificationException没有抛出(http://stackoverflow.com/questions/ 24980651/java-util-concurrentmodificationexception -with-thrown-when-expected) – Pshemo
我喜欢Sun没有做出改变的原因是它可能会让一些不好的代码实际上开始抛出它应该抛出的异常 – Mshnik