为什么 ArrayList 大小字段不是瞬态的?
Why is the ArrayList size field not transient?
Java 的 ArrayList
使用自定义序列化并显式写入 size
。然而,ArrayList
中未将大小标记为 transient
。为什么大小写了两次:一次通过 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]);
}
TL;DR
它的存在只是为了与旧 java 版本兼容。
详情
如果你看一下上面的评论 s.writeInt(size)
,你会发现这应该是容量。在以前的 java 版本中,ArrayList
的序列化形式具有大小和容量。
两者都代表ArrayList
的实际属性。 size
表示 ArrayList
中的项目数,而 capacity
表示其中可能的项目数(数组长度),无需重新创建数组。
如果你看一下readObject
,你会发现容量被忽略了:
// Read in capacity
s.readInt(); // ignored
这是因为它在以前的 java 版本中使用,并且仍然需要 written/read 以保持兼容性。
如果你查看the matching JDK6 sources,你会发现这实际上是以前使用过的。如果你有一个序列化的 JDK6 ArrayList
并尝试用更新的 JDK 反序列化它,它会起作用。但是,如果刚刚跳过容量,这将失败,并且您无法使用旧版本的 ArrayList
反序列化任何内容。
Java 的 ArrayList
使用自定义序列化并显式写入 size
。然而,ArrayList
中未将大小标记为 transient
。为什么大小写了两次:一次通过 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]);
}
TL;DR
它的存在只是为了与旧 java 版本兼容。
详情
如果你看一下上面的评论 s.writeInt(size)
,你会发现这应该是容量。在以前的 java 版本中,ArrayList
的序列化形式具有大小和容量。
两者都代表ArrayList
的实际属性。 size
表示 ArrayList
中的项目数,而 capacity
表示其中可能的项目数(数组长度),无需重新创建数组。
如果你看一下readObject
,你会发现容量被忽略了:
// Read in capacity
s.readInt(); // ignored
这是因为它在以前的 java 版本中使用,并且仍然需要 written/read 以保持兼容性。
如果你查看the matching JDK6 sources,你会发现这实际上是以前使用过的。如果你有一个序列化的 JDK6 ArrayList
并尝试用更新的 JDK 反序列化它,它会起作用。但是,如果刚刚跳过容量,这将失败,并且您无法使用旧版本的 ArrayList
反序列化任何内容。