[英]Why does ArrayList use transient storage?
I was reading the source of Java's ArrayList and I came across its backing array declaration:我正在阅读 Java 的 ArrayList 的源代码,我遇到了它的支持数组声明:
private transient Object[] elementData;
Why does this need to be transient?为什么这需要是短暂的? Why can't this class be serialized?
为什么这个类不能序列化?
Thanks for the help!谢谢您的帮助!
It can be serialized;可以序列化; the
ArrayList
class just takes care of things itself, rather than using the default mechanism. ArrayList
类只是自己处理事情,而不是使用默认机制。 Look at the writeObject()
and readObject()
methods in that class, which are part of the standard serialization mechanism.查看该类中的
writeObject()
和readObject()
方法,它们是标准序列化机制的一部分。
If you look at the source, you see that writeObject()
does not save the backing array.如果查看源代码,您会看到
writeObject()
不保存支持数组。 Instead, it serializes the elements (including null values) one at a time up to the size()
limit.相反,它一次一个地序列化元素(包括空值),直至达到
size()
限制。 This avoids the overheads of serializing the array, and especially any unused slots at the end of the array.这避免了序列化数组的开销,尤其是数组末尾的任何未使用的插槽。 On deserialization, a new backing array of the minimum required size is created by
readObject()
.在反序列化时,
readObject()
创建一个最小所需大小的新支持数组。
Why does this need to be transient?
为什么这需要是短暂的?
It does this because it provides custom readObject
and writeObject
methods that do a better job of serialization than the default.它这样做是因为它提供了自定义的
readObject
和writeObject
方法,这些方法比默认的序列化工作做得更好。 Specifically, the writeObject method writes just the size and the sequence of elements.具体来说,writeObject 方法只写入元素的大小和序列。 This avoids serializing the private array object which 1) has its own header and overheads, and 2) is typically padded with
null
s.这避免了序列化私有数组对象,该对象 1) 具有自己的标头和开销,并且 2) 通常用
null
填充。 The space saving can be significant.空间节省可能是显着的。
Why can't this class be serialized?
为什么这个类不能序列化?
The ArrayList
class as a whole can be serialized 1 . ArrayList
类作为一个整体可以序列化1 。 The Object[]
could be serialized directly, but they chose to mark it as transient
implement the serialization another way. Object[]
可以直接序列化,但他们选择将其标记为transient
以另一种方式实现序列化。
1 - Actually, this depends on the elements' runtime types. 1 - 实际上,这取决于元素的运行时类型。 For example, if you attempted to serialize an
ArrayList
containing Thread
references, then you would get a runtime exception for the first non-null reference.例如,如果您尝试序列化包含
Thread
引用的ArrayList
,那么您将收到第一个非空引用的运行时异常。
ArrayList
实现了Serializable
,因此它可以被序列化,这正是私有后备数组是transient
,因此它不会与类中的其他数据一起序列化,因为所有这些都是由ArrayList
的writeObject
和readObject
方法处理的。
Because it implements explicit serialization.因为它实现了显式序列化。 See ArrayList#writeObject.
请参见 ArrayList#writeObject。
Extending on Stephen C's answer above, I would like to correct his note about transient being used, in ArrayLists
's case, for readability.扩展上面斯蒂芬 C 的回答,我想更正他关于在
ArrayLists
的情况下使用瞬态的注释,以提高可读性。 This may be better as a comment under his answer but I don't have that ability yet!在他的回答下作为评论可能会更好,但我还没有那种能力!
While the field being marked as transient
is helpful for readability, it is also necessary due to the custom readObject
and writeObject
methods calling java.io.ObjectInputStream
's defaultReadObject
and java.io.ObjectOutputStream
's defaultWriteObject
methods respectively.虽然将字段标记为
transient
有助于提高可读性,但由于自定义readObject
和writeObject
方法分别调用java.io.ObjectInputStream
的defaultReadObject
和java.io.ObjectOutputStream
的defaultWriteObject
方法,这也是必要的。 These methods will do the dirty work of handling serializiation of all the fields not marked transient
(eg size
).这些方法将完成处理所有未标记为
transient
(例如size
)的字段的序列化的肮脏工作。
See the source code for ObjectOutputStream
for more details here: https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/io/ObjectOutputStream.java#L431有关更多详细信息,请参阅
ObjectOutputStream
的源代码: https : //github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/io/ObjectOutputStream.java#L431
The variable isn't serializable.该变量不可序列化。
The variable is redundant.变量是多余的。
link: http://onjava.com/pub/a/onjava/excerpt/JavaRMI_10/index.html?page=3链接: http : //onjava.com/pub/a/onjava/excerpt/JavaRMI_10/index.html?page=3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.