为什么 ArrayList 的 size 字段不是瞬态的?

3
Java的ArrayList使用自定义序列化并显式写入大小。尽管如此,在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]);
}
1个回答

6

简述

ArrayList类的sizecapacity两个属性在旧版的Java中序列化时都会被记录下来,但这只是为了与旧版Java的兼容性而存在。

详细说明

如果你仔细阅读s.writeInt(size)上面的注释,你会发现这其实应该是指ArrayList的容量。在旧版的Java中,ArrayList的序列化格式包含了sizecapacity两个属性。

实际上,size代表的是ArrayList中元素的数量,而capacity则是指ArrayList当前数组中可以容纳的元素数量(即数组长度),在不需要重新创建数组的情况下。

但是,在readObject函数中,程序却忽略了capacity这个属性:

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

这是因为它在之前的Java版本中被使用过,而且仍然需要编写/读取以保持兼容性。

如果您查看相应的JDK6源代码,您会发现确实曾经使用过此功能。如果您有一个序列化的JDK6 ArrayList 并尝试使用更新的JDK进行反序列化,它将工作。但是,如果容量被跳过,这将失败,并且无法反序列化任何旧版本的ArrayList


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接