java - 为什么 ArrayList 大小字段不是 transient 的?

标签 java serialization java-custom-serialization

Java 的ArrayList 使用自定义序列化并显式写入大小。尽管如此,ArrayList 中的大小并未标记为 transient。为什么 size 写了两次:一次是通过 defaultWriteObject ,另一次是通过 writeInt(size) ,如下所示(writeObject 方法)?

s.defaultWriteObject();

// Write out size as capacity for behavioral 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]);
}

最佳答案

长话短说

它的存在仅仅是为了与旧的 java 版本兼容。

详情

如果您看一下 s.writeInt(size) 上面的注释,您会发现这应该是容量。在以前的 java 版本中,ArrayList 的序列化形式具有大小和容量。

它们都表示 ArrayList 的实际属性。 size 表示 ArrayList 中的项目数,而 capacity 表示其中可能项目的数量(数组的长度)无需重新创建数组。

如果查看 readObject,您会发现容量被忽略了:

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

这是因为它在以前的 java 版本中使用,仍然需要写入/读取以保持兼容性。

如果你看the matching JDK6 sources ,你可以看到这实际上是以前使用过的。如果您有序列化的 JDK6 ArrayList 并尝试使用较新的 JDK 对其进行反序列化,它将起作用。但是,如果刚刚跳过容量,这将失败,并且您无法使用旧版本的 ArrayList 反序列化任何内容。

关于java - 为什么 ArrayList 大小字段不是 transient 的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71474228/

相关文章:

java - 开始使用 Maven

java - 如何将 @UIBinder 与 CheckBox ValueChangeEvent 一起使用?

java - 在java中的HTTP请求中生成PDF作为输出流

java - 为什么 SonarQube 在类序列化时给出 transient /私有(private)错误?

java - 如何序列化其方法有多个参数的对象

java - 如何使用特定注释将自定义序列化器设置为任意 API 端点(spring 应用程序)?

java - 当我更新 JTable 中的数据库时,我得到多个项目

javascript - 如何将其序列化为 JSON?

c# - 将数据存储在 C# 源文件与 XML 等...?