从Java 8开始,ArrayList
使用接下来的writeObject
和readObject
方法进行序列化:
/**
* Save the state of the <tt>ArrayList</tt> instance to a stream (that
* is, serialize it).
*
* @serialData The length of the array backing the <tt>ArrayList</tt>
* instance is emitted (int), followed by all of its elements
* (each an <tt>Object</tt>) in the proper order.
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out size as capacity for behavioural compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
/**
* Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
* deserialize it).
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in capacity
s.readInt(); // ignored
if (size > 0) {
// be like clone(), allocate array based upon size not capacity
ensureCapacityInternal(size);
Object[] a = elementData;
// Read in all elements in the proper order.
for (int i=0; i<size; i++) {
a[i] = s.readObject();
}
}
}
ArrayList.size
字段仅具有private
修饰符。它使用out.defaultWriteObject
方法序列化。 readObject
方法中不使用它(我的意思是不使用反义化值)。为什么size
第二次使用s.writeInt(size);
添加到序列化流中?
我看到有一个类似// Write out size as capacity for behavioural compatibility with clone()
的评论。但是我无法理解size
,writeObjectMethod
和clone()
中的大小双序列化之间的关系。
答案 0 :(得分:2)
通常这种事情是为了版本之间的兼容性。 spec says
发出支持ArrayList实例的数组的长度(int),然后按正确的顺序发出其所有元素(每个Object)。
诚然,规范通常丢失或错误。无论如何,它都应该与JRE 1.2.0所做的任何读写兼容。
我现在检查了,旧版本使用它作为容量。没有容量字段,因为在一个实例中elementData.length
可以获取真实值,但不会以其他方式写入流中。