ArrayList集合中的elementData为什么不参与序列化?
Posted deters
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayList集合中的elementData为什么不参与序列化?相关的知识,希望对你有一定的参考价值。
在ArrayList中有这么一段代码
/** * 存储ArrayList元素的数组缓冲区。ArrayList的容量是此数组缓冲区的长度。
* 添加第一个元素时,任何带有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList都将扩展为DEFAULT_CAPACITY。 */ transient Object[] elementData; // non-private to simplify nested class access
elementData是存放当前集合中所有的元素的一个数组,但是却被transient关键字修饰,transient表示该数组不参与序列化.
那这样的话,序列化之后ArrayList中存放的元素不就丢失了吗?
带着这样的疑问接着往下看,最后发现在ArrayList中有这样两个方法 writeObject() 和 readObject()
/** * 将 ArrayList 实例的状态保存到流(即序列化它)。*/ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException // 写出元素计数和任何隐藏的东西 int expectedModCount = modCount; s.defaultWriteObject(); // 写出当前类的所有非静态字段(non-static)和非瞬态字段(non-transient)到ObjectOutputStream // 将size写出到ObjectOutputStream s.writeInt(size); // 因为ArrayList是可扩容的,在添加元素时,可能会扩容,这个时候会存在一些没有使用的空间,所以采用这种方式,来节约空间和减少序列化的时间 for (int i=0; i<size; i++) // size代表数组中储存的元素的个数 s.writeObject(elementData[i]); // 有序的将elementData中已使用的元素读出到流中 if (modCount != expectedModCount) throw new ConcurrentModificationException();
/** * 从流中重构 ArrayList 实例(即,对其进行反序列化)。 */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException elementData = EMPTY_ELEMENTDATA; // 读入size, 和所有隐藏的东西 s.defaultReadObject(); // 读入容量 s.readInt(); // ignored if (size > 0) // 就像clone()一样,根据大小而不是容量来分配数组 ensureCapacityInternal(size); Object[] a = elementData; // 按正确的顺序读入所有元素。 for (int i=0; i<size; i++) a[i] = s.readObject();
以上是关于ArrayList集合中的elementData为什么不参与序列化?的主要内容,如果未能解决你的问题,请参考以下文章
java集合-ArrayList中EMPTY_ELEMENTDATA与DEFAULTCAPACITY_EMPTY_ELEMENTDATA的区别