Java 为什么';编译器无法发现ConcurrentModificationException的某些原因

Java 为什么';编译器无法发现ConcurrentModificationException的某些原因,java,iterator,javac,Java,Iterator,Javac,很明显,这段代码在迭代过程中修改了一个列表 public class ArrayIterator { public static void main(String[] args) { List<String> list = new LinkedList<>(Arrays.asList("A","B","C","D","E")); Iterator<String> it = list.iterator();

很明显,这段代码在迭代过程中修改了一个列表

public class ArrayIterator {

    public static void main(String[] args) {

        List<String> list = new LinkedList<>(Arrays.asList("A","B","C","D","E"));

        Iterator<String> it = list.iterator();
        while (it.hasNext())
        {
            list.remove(it.next());
        }

    }
}

为什么编译器不能对此发出警告?

java.util.ConcurrentModificationException是一个运行时异常。它可能(也可能不会)发生。在某些情况下,您可能希望
remove()
在迭代集合时引发此异常,但根据元素的数量和当前元素的位置,不会发生异常

例如,以下情况不会引发异常:

List<String> list = new LinkedList<String>(Arrays.asList("A", "B", "C", "D", "E"));
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String next = it.next();
    if(next.equals("D")) {
        list.remove(next);
    }
}
List<String> list = new LinkedList<String>(Arrays.asList("A", "B", "C", "D", "E"));
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String next = it.next();
    if(next.equals("C")) {
        list.remove(next);
    }
}
List List=newlinkedlist(Arrays.asList(“A”、“B”、“C”、“D”、“E”));
Iterator it=list.Iterator();
while(it.hasNext()){
String next=it.next();
如果(下一个等于(“D”)){
列表。删除(下一步);
}
}
另一方面,以下命令引发异常:

List<String> list = new LinkedList<String>(Arrays.asList("A", "B", "C", "D", "E"));
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String next = it.next();
    if(next.equals("D")) {
        list.remove(next);
    }
}
List<String> list = new LinkedList<String>(Arrays.asList("A", "B", "C", "D", "E"));
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String next = it.next();
    if(next.equals("C")) {
        list.remove(next);
    }
}
List List=newlinkedlist(Arrays.asList(“A”、“B”、“C”、“D”、“E”));
Iterator it=list.Iterator();
while(it.hasNext()){
String next=it.next();
如果(下一个等于(“C”)){
列表。删除(下一步);
}
}

<代码> > p>编译器不考虑代码的逻辑,只有合法的。

例如:

public void explode(int i) {
    System.out.println(1 / (i - i)); // always divide by zero
}
这将始终抛出一个
算术异常
,但它编译得很好


您的代码是一个不太明显的例子。

编译器了解Java语言。它不知道构成Java标准库的数千个类中的任何一个类的API契约(可能除了
Java.lang
包中的一些类)。

您不能使用
\remove()
方法删除元素吗?@screenmutt OP故意使用
List\remove
。OP:我真的不认为编译器应该能够处理这个问题,边缘情况可能是删除由递归方法遍历的
集合
中的一个项,在该方法中您只知道使用
集合#remove
。出于同样的原因,编译器在编译过程中不会尝试查找ArrayIndexOutOfBoundsException的可证明实例-这不是唯一的方法编译器处理这些语义问题的责任。因为有些集合允许在迭代时被修改。因为知道API中所有类的内部实现细节并不是编译器的工作。它的工作是检查代码的语法是否正确。您应该使用
it.remove()
而不是
list.remove()
,而且编译器不会警告您,因为这是
运行时
异常。@VinceEmigh并解释原因。基本上,这是因为迭代器无法实现元素已被删除,其
hasNext()
返回false,不允许
next()
引发异常。