为什么LinkedList中的writeObject方法不检查ConcurrentModificationException

时间:2015-07-21 13:15:59

标签: java

为什么在LinkedList中重载方法writeObject不会像ArrayList那样检查ConcurrentModificationException。
我看过LinkedList的java代码

private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        // Write out any hidden serialization magic
        s.defaultWriteObject();

        // Write out size
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (Node<E> x = first; x != null; x = x.next)
            s.writeObject(x.item);
    }

ArrayList的java代码

private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject();

        // Write out size as capacity for behavioural compatibility with clone()
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (int i=0; i<size; i++) {
            s.writeObject(elementData[i]);
        }

        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }

可能的原因是什么。

3 个答案:

答案 0 :(得分:1)

首先观察:ArrayListLinkedList的javadoc没有说明在序列化时是否执行了并发修改检查。因此,它与各自的API合同是否一致,可以进行检查。

那他们为什么会有所不同?

在没有检查Java源代码历史的情况下,一直回到Java 1.1,我们只能猜测。它可能是一个疏忽,或者是在一个类而不是另一个类中进行的早期错误修复。也可能是注意到了不一致,但由于担心修复会破坏客户代码,因此没有修复。

我在Java Bug数据库中找不到任何相关的错误报告。

答案 1 :(得分:1)

在分析代码后,我猜在LinkedList中显然是 bug

请注意,它首先要做的是在流上写入列表的 size ,然后写入其节点。但是,如果在序列化列表时添加/删除某个节点,则已经写入的大小的值不再是与实际序列化的节点数。

序列化LinkedList的客户端最终会得到一个声明5个元素但只有4个的ObjectStream。(这最终会在readObject中产生异常。)

答案 2 :(得分:0)

我认为有一个原因可能是LinkList在写入期间抛出了IndexOutOfBoundException(你不能同时在它上面写) 我不确定并且需要对此进行测试。