java.util.ConcurrentModificationException 没有按预期抛出

标签 java exception

以下代码抛出 java.util.ConcurrentModificationException , 正如预期的那样:

   public void test(){
      ArrayList<String> myList = new ArrayList<String>();

      myList.add("String 1");
      myList.add("String 2");
      myList.add("String 3");
      myList.add("String 4");
      myList.add("String 5");

      for(String s : myList){
         if (s.equals("String 2")){
            myList.remove(s);
         }
      }
   }

但是,下面的代码不会抛出异常,而我预计它会抛出:

   public void test(){
      ArrayList<String> myList = new ArrayList<String>();

      myList.add("String 1");
      myList.add("String 2");
      myList.add("String 3");

      for(String s : myList){
         if (s.equals("String 2")){
            myList.remove(s);
         }
      }
   }

区别在于第一个列表包含5个项目,而第二个列表包含3个。使用的JVM是:

java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

问题:为什么第二段代码抛出 java.util.ConcurrentModificationException?

最佳答案

在实现中从 ArrayList.iterator() 返回的迭代器,我们显然都只检查调用 next() 时的结构修改,调用hasNext()。后者看起来像这样(在 Java 8 下):

public boolean hasNext() {
    return cursor != size;
}

所以在你的第二种情况下,迭代器“知道”它返回了两个元素,并且列表只有两个元素...所以hasNext()只是返回 false,我们永远不会第三次调用 next()

我认为这是一个实现细节——基本上检查没有达到应有的严格程度。在这种情况下,hasNext() 执行检查并抛出异常也是完全合理的。

关于java.util.ConcurrentModificationException 没有按预期抛出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24980651/

相关文章:

.net - 在运行时获取 OutofMemoryException 消息 "Insufficient memory to continue the execution of the program"

java - 替换 Arraylist 中的空值

java - 如何使用Java编程将xml记录从一个xml文件复制到另一个文件?

java - Java中删除链表中的节点

c++ - 何时捕获 boost::bad lexical_cast

c# - 检查 null 线程安全吗?

php - Laravel 处理异常

java - Drawable.createFromStream 和 getResources().getDrawable,为什么它们的输出不同?

java - Jackson在同一个类中根据json映射不同的属性

java - android sqlite数据库表重建