我正在阅读Java的ArrayList的源代码,我遇到了它的支持数组声明:
private transient Object[] elementData;
为什么这需要是暂时的?为什么不能将这个类序列化?
谢谢您的帮助!
它可以序列化; ArrayList
类只是处理事物本身,而不是使用默认机制。查看该类中的writeObject()
和readObject()
方法,它们是标准序列化机制的一部分。
如果查看源代码,您会看到writeObject()
不保存支持数组。相反,它一次一个地序列化元素(包括空值),直到size()
限制。这避免了序列化阵列的开销,尤其是阵列末尾的任何未使用的槽。在反序列化时,readObject()
创建了所需最小大小的新后备数组。
为什么这需要是暂时的?
它这样做是因为它提供了自定义readObject
和writeObject
方法,这些方法比默认方法更好地进行序列化。具体来说,writeObject方法只写入元素的大小和顺序。这样可以避免序列化私有数组对象,该对象1)有自己的头和开销,2)通常用null
s填充。节省空间可能很重要。
为什么不能将这个类序列化?
ArrayList
类作为一个整体可以序列化1。 Object[]
可以直接序列化,但是他们选择将其标记为transient
以另一种方式实现序列化。
1 - 实际上,这取决于元素的运行时类型。例如,如果您尝试序列化包含ArrayList
引用的Thread
,那么您将获得第一个非null引用的运行时异常。
ArrayList
实现了Serializable
,所以它可以被序列化,这正是私有后备数组是transient
的原因,所以它没有与类中的其他数据一起序列化,因为所有都是由ArrayList
的writeObject
和readObject
方法处理的。
因为它实现了显式序列化。请参见ArrayList#writeObject。
根据Stephen C上面的答案,我想纠正他关于瞬态使用的注释,在ArrayLists
的情况下,为了可读性。根据他的回答,这可能会更好,但我还没有这个能力!
虽然标记为transient
的字段有助于提高可读性,但由于自定义readObject
和writeObject
方法分别调用java.io.ObjectInputStream
的defaultReadObject
和java.io.ObjectOutputStream
的defaultWriteObject
方法,因此也是必要的。这些方法将处理所有未标记为transient
(例如size
)的字段的序列化的脏工作。
有关更多详细信息,请参阅ObjectOutputStream
的源代码:https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/io/ObjectOutputStream.java#L431
该变量不可序列化。
变量是多余的。
链接:http://onjava.com/pub/a/onjava/excerpt/JavaRMI_10/index.html?page=3