为什么Java ArrayList明确在序列化流中写入size字段?

时间:2018-10-07 20:46:38

标签: java arraylist serialization

从Java 8开始,ArrayList使用接下来的writeObjectreadObject方法进行序列化:

/**
     * Save the state of the <tt>ArrayList</tt> instance to a stream (that
     * is, serialize it).
     *
     * @serialData The length of the array backing the <tt>ArrayList</tt>
     *             instance is emitted (int), followed by all of its elements
     *             (each an <tt>Object</tt>) in the proper order.
     */
    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();
        }
    }

    /**
     * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
     * deserialize it).
     */
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;

        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // Read in capacity
        s.readInt(); // ignored

        if (size > 0) {
            // be like clone(), allocate array based upon size not capacity
            ensureCapacityInternal(size);

            Object[] a = elementData;
            // Read in all elements in the proper order.
            for (int i=0; i<size; i++) {
                a[i] = s.readObject();
            }
        }
    }

ArrayList.size字段仅具有private修饰符。它使用out.defaultWriteObject方法序列化。 readObject方法中不使用它(我的意思是不使用反义化值)。为什么size第二次使用s.writeInt(size);添加到序列化流中? 我看到有一个类似// Write out size as capacity for behavioural compatibility with clone()的评论。但是我无法理解sizewriteObjectMethodclone()中的大小双序列化之间的关系。

1 个答案:

答案 0 :(得分:2)

通常这种事情是为了版本之间的兼容性。 spec says

  

发出支持ArrayList实例的数组的长度(int),然后按正确的顺序发出其所有元素(每个Object)。

诚然,规范通常丢失或错误。无论如何,它都应该与JRE 1.2.0所做的任何读写兼容。

我现在检查了,旧版本使用它作为容量。没有容量字段,因为在一个实例中elementData.length可以获取真实值,但不会以其他方式写入流中。