java - 为什么 Java ArrayList 会在序列化流中显式写入大小字段?

标签 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 方法中使用(我的意思是没有使用 deserealized 值)。为什么第二次使用s.writeInt(size);size 添加到序列化流中? 我看到,有这样的注释://Write out size as capacity for behavioral compatibility with clone()。但是我无法理解 size 之间的关系,writeObjectMethodclone() 中的大小双序列化。

最佳答案

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

The length of the array backing the ArrayList instance is emitted (int), followed by all of its elements (each an Object) in the proper order.

诚然,规范通常缺失或错误。在任何情况下,它都应该与 JRE 1.2.0 所做的任何操作兼容读写。

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

关于java - 为什么 Java ArrayList 会在序列化流中显式写入大小字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52692771/

相关文章:

Java:在范围退出时自动调用函数(如 C++ 析构函数)

java - IBM purequery 是否有任何有效的开源替代方案来查询内存中的集合?

java - 以最高安全设置运行java

java - 如何通过属性使用流来过滤对象?

c# - 一次反序列化json数组流一项

c# - 如何在 Unity 中序列化和反序列化包含 Gameobject 和 Vector2 的字典

Linux EC2 实例和 Openfire 服务器中的 Java CPU 使用率超过 100%

java - 为什么在 Sort() 之后 ArrayList 的开头是 10

java - Groovy-List、ArrayList 和 Object Array 的区别

c#比较两个对象模型中的数据