为什么ArrayList使用瞬态存储?
我正在阅读Java的ArrayList的源代码,我遇到了它的支持数组声明:
private transient Object[] elementData;
为什么这需要是暂时的? 为什么不能将这个类序列化?
谢谢您的帮助!
它可以序列化; ArrayList
类只是处理事物本身,而不是使用默认机制。 查看该类中的writeObject()
和readObject()
方法,它们是标准序列化机制的一部分。
如果查看源代码,您会发现writeObject()
不保存支持数组。 相反,它一次一个地序列化元素(包括空值),直到size()
限制。 这避免了序列化arrays的开销,尤其是arrays末尾的任何未使用的槽。 在反序列化时, readObject()
创建了所需最小大小的新后备数组。
为什么这需要是暂时的?
它这样做是因为它提供了自定义的readObject
和writeObject
方法,这些方法比默认方法更好地进行序列化。 具体来说,writeObject方法只写入元素的大小和顺序。 这避免了序列化私有数组对象,其中1)具有其自己的头和开销,并且2)通常用null
s填充。 节省空间可能很重要。
(事实上,我认为该字段根本不需要被声明为transient
,但它确实有助于记录开发人员的意图。)
为什么不能将这个类序列化?
ArrayList
类作为一个整体可以序列化1 。 Object[]
可以序列化,但是他们选择以另一种方式实现它。
1 – 实际上,这取决于元素的运行时类型。 例如,如果您尝试序列化包含Thread
引用的ArrayList
,那么您将获得第一个非null引用的运行时exception。
ArrayList
实现Serializable
,因此它可以被序列化,这正是私有后备数组是transient
,因此它不与类中的其他数据一起序列化,因为所有数据都由ArrayList
的writeObject
和readObject
方法处理。
因为它实现了显式序列化。 请参见ArrayList#writeObject。
该变量不可序列化
- 如果变量不可序列化,那么序列化机制在尝试序列化变量时将抛出exception。 为避免这种情况,您可以将变量声明为瞬态变量。
变量是多余的
- 假设实例缓存计算结果。 在本地,我们可能希望存储计算结果,以节省一些处理器时间。 但是当我们通过线路发送对象时,我们可能更担心消耗带宽,从而丢弃缓存的计算,因为我们以后总是可以重新生成它。
链接: http : //onjava.com/pub/a/onjava/excerpt/JavaRMI_10/index.html?page = 3