Why does ArrayList use transient storage?

前端 未结 6 1160
既然无缘
既然无缘 2020-12-24 05:55

I was reading the source of Java\'s ArrayList and I came across its backing array declaration:

private transient Object[] elementData;

Why

相关标签:
6条回答
  • 2020-12-24 06:33

    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 nulls. The space saving can be significant.

    Why can't this class be serialized?

    The ArrayList class as a whole can be serialized1. 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.

    0 讨论(0)
  • 2020-12-24 06:33

    Because it implements explicit serialization. See ArrayList#writeObject.

    0 讨论(0)
  • 2020-12-24 06:37

    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().

    0 讨论(0)
  • 2020-12-24 06:39

    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 (e.g. 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

    0 讨论(0)
  • 2020-12-24 06:39

    The variable isn't serializable.

    • If the variable isn't serializable, then the serialization mechanism will throw an exception when it tries to serialize the variable. To avoid this, you can declare the variable to be transient.

    The variable is redundant.

    • Suppose that the instance caches the result of a computation. Locally, we might want to store the result of the computation, in order to save some processor time. But when we send the object over the wire, we might worry more about consuming bandwidth and thus discard the cached computation since we can always regenerate it later on.

    link: http://onjava.com/pub/a/onjava/excerpt/JavaRMI_10/index.html?page=3

    0 讨论(0)
  • 2020-12-24 06:40

    ArrayList implements Serializable, so it can be serialized, that's exactly why the private backing array is transient, so it is not serialized along with other data in the class, since all is handled by ArrayList's writeObject and readObject methods.

    0 讨论(0)
提交回复
热议问题