简体   繁体   English

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

[英]Why is the ArrayList size field not transient?

Java's ArrayList uses custom serialization and explicitly writes the size . Java 的ArrayList使用自定义序列化并显式写入size Nevertheless, size is not marked in ArrayList as transient .然而,大小没有在ArrayList中标记为transient Why is size written two times: once via defaultWriteObject and again vis writeInt(size) as shown below ( writeObject method)?为什么 size 写了两次:一次是通过defaultWriteObject ,另一次是 vis 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长话短说

It exists solely for compatibility with old java versions.它的存在仅仅是为了与旧的 java 版本兼容。

details细节

If you take a look at the comment above s.writeInt(size) , you can see that this is supposed to be the capacity.如果您查看s.writeInt(size)上面的注释,您会发现这应该是容量。 In previous java versions, the serialized form of ArrayList had a size and a capacity.在之前的 java 版本中, ArrayList的序列化形式具有大小和容量。

Both of them represent actual properties of an ArrayList .它们都代表ArrayList的实际属性。 The size represents the number of items in the ArrayList while the capacity refers to the number of of possible items (length of the array) in it without the array needing to be recreated. size表示ArrayList中的项数,而capacity是指在不需要重新创建数组的情况下其中可能的项数(数组的长度)。

If you take a look at readObject , you can see that the capacity is ignored:如果您查看readObject ,您会发现容量被忽略了:

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

This is because it was used in previous java versions and it still needs to be written/read to preserve compatibility.这是因为它在以前的 java 版本中使用,仍然需要写入/读取以保持兼容性。

If you look at the matching JDK6 sources , you can see that this was in fact used previously.如果您查看匹配的 JDK6 源代码,您会发现这实际上是以前使用过的。 If you have a serialized JDK6 ArrayList and try to deserialize it with a newer JDK, it will work.如果你有一个序列化的 JDK6 ArrayList并尝试用更新的 JDK 反序列化它,它会起作用。 But if the capacity was just skipped, this would fail and you couldn't deserialize anything with an ArrayList from that old version.但是,如果刚刚跳过容量,这将失败,并且您无法使用旧版本中的ArrayList反序列化任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM