I was reading the source of Java's ArrayList and I came across its backing array declaration:
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. Look at the writeObject()
and readObject()
methods in that class, which are part of the standard serialization mechanism.
If you look at the source, you see that writeObject()
does not save the backing array. Instead, it serializes the elements (including null values) one at a time up to the size()
limit. 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()
.
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. Specifically, the writeObject method writes just the size and the sequence of elements. This avoids serializing the private array object which 1) has its own header and overheads, and 2) is typically padded with null
s. The space saving can be significant.
Why can't this class be serialized?
The ArrayList
class as a whole can be serialized 1 . The Object[]
could be serialized directly, but they chose to mark it as transient
implement the serialization another way.
1 - Actually, this depends on the elements' runtime types. 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.
ArrayList
实现了Serializable
,因此它可以被序列化,这正是私有后备数组是transient
,因此它不会与类中的其他数据一起序列化,因为所有这些都是由ArrayList
的writeObject
和readObject
方法处理的。
Because it implements explicit serialization. See 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. 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. These methods will do the dirty work of handling serializiation of all the fields not marked transient
(eg 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
The variable isn't serializable.
The variable is redundant.
link: http://onjava.com/pub/a/onjava/excerpt/JavaRMI_10/index.html?page=3
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.