主要依赖重写readObject()和writeObject()方法;
实现原理:
写操作(Serialization)
实现了Serializable接口,表明其实例可以被序列化,仅序列化size字段,其elementData数组被定义为transient,不会被序列化,因为elementData数组内容过大,直接序列化效率低下,且ArrayList大小可变,序列化时数组大小不代表最终大小,所以只serialize size,在反序列化时根据size重新构建elementData数组
读操作(Deserialization)
在readObject()方法中,首先读取序列化的size字段;如果size == 0,直接将elementData置为EMPTY_ELEMENTDATA,否则根据size创建新的elementData数组,然后通过循环调用输入流size次,读取elementData的每个元素,实现反序列化,通过size重新构建elementData数组并填充元素,实现ArrayList的反序列化
writeObject()介绍:
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out element count, and any hidden stuff
//首先记录当前modCount字段的值到expectedModCount变量,这是为了后续检测数组在序列化过程中是否被修改
int expectedModCount = modCount;
//将普通字段(non-transient)如size等写入流中
s.defaultWriteObject();
//将size字段的值写入流中,作为容量来写
// Write out size as capacity for behavioral compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
//然后通过循环将elementData数组的每个元素写入流中,完成序列化
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
//比较modCount和expectedModCount。
//如果不相等,说明数组内容在序列化过程中被修改,抛出ConcurrentModificationException异常
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
readObject介绍:
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in size, and any hidden stuff
//读取普通字段信息如size
s.defaultReadObject();
//
// Read in capacity
s.readInt(); // ignored
if (size > 0) {
// like clone(), allocate array based upon size not capacity
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
//根据size创建elementData数组
Object[] elements = new Object[size];
// Read in all elements in the proper order.
//循环读取输入流填充elementData数组
for (int i = 0; i < size; i++) {
elements[i] = s.readObject();
}
elementData = elements;
} else if (size == 0) {
elementData = EMPTY_ELEMENTDATA;
} else {
throw new java.io.InvalidObjectException("Invalid size: " + size);
}
}