Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

exception - java.util.ConcurrentModificationException not thrown when expected

The following code throws a java.util.ConcurrentModificationException, as expected:

   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);
         }
      }
   }

However, the following code does not throw the Exception, while I expect it to be thrown:

   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);
         }
      }
   }

The difference is that the first list contains 5 items, while the second list contains 3. The JVM used is:

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)

The question: why does the second piece of code NOT throw the java.util.ConcurrentModificationException?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The iterator returned from ArrayList.iterator() in the implementation we're apparently both using only checks for structural modification in calls to next(), not in calls to hasNext(). The latter just looks like this (under Java 8):

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

So in your second case, the iterator "knows" that it's returned two elements, and that the list only has two elements... so hasNext() just returns false, and we never end up calling next() the third time.

I would view this as an implementation detail - basically the checking not being as strict as it could be. It would be entirely reasonable for hasNext() to perform a check and throw an exception in this case too.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...