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/