Java中集合使用增强for循环进行遍历抛出ConcurrentModificationException

在ArrayList底层原理中,介绍了:使用集合的迭代器类对集合进行迭代时,迭代器会记录下当前modCount(每当调用add等方法时,modCount会+1)的值,在通过迭代器遍历集合容器的过程中(使用迭代器的next、previous、set、remove、add方法),会一直判断modCount与一开始记录的值是否相同,若不同则抛出ConcurrentModificationException。

但在实际开发中,发现使用增强for循环遍历集合,有时也会抛出ConcurrentModificationException。这里通过编译自己写的一段代码找到了答案。

Java代码如下:

Java中集合使用增强for循环进行遍历抛出ConcurrentModificationException_第1张图片

使用javap -c -l Main.class编译class文件后,输出的信息如下。LineNumberTable下的数字是Java文件的代码行与该代码行编译后的在编译信息中的行号。观察main方法中的编译代码,当执行到for循环时,通过编译信息第27行可以看到:执行了List的Iterator方法,然后通过迭代器的hasNext()和next()方法来进行遍历。

Compiled from "Main.java"
public class com.zkw.Main {
  public com.zkw.Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: return
    LineNumberTable:
      line 10: 0

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/util/ArrayList
       3: dup
       4: invokespecial #3                  // Method java/util/ArrayList."":()V
       7: astore_1
       8: aload_1
       9: ldc           #4                  // String a
      11: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      16: pop
      17: aload_1
      18: ldc           #6                  // String b
      20: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      25: pop
      26: aload_1
      27: invokeinterface #7,  1            // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      32: astore_2
      33: aload_2
      34: invokeinterface #8,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
      39: ifeq          62
      42: aload_2
      43: invokeinterface #9,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      48: checkcast     #10                 // class java/lang/String
      51: astore_3
      52: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
      55: aload_3
      56: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      59: goto          33
      62: return
    LineNumberTable:
      line 13: 0
      line 14: 8
      line 15: 17
      line 17: 26
      line 18: 52
      line 19: 59
      line 20: 62
}

所以我们得出结论,通过增强for循环来遍历集合框架,其实就是调用其Iterator方法来进行的迭代。若想更详细的了解Java集合通过Iterator遍历时抛出ConcurrentModificationException的原因,可以参考:ArrayList底层原理。

你可能感兴趣的:(java基础)