ArrayList的序列化的实现(详解)

ArrayList的序列化的实现

  • 解读
    • ArrayList底层是怎样通过Object数组完成存储
  • 知识拓展
    • 为什么底层数组使用transient

解读

在序列化的过程中,如果被序列化的类定义了writeObject和readObject方法,虚拟机会试图调用对象类里面的writeObject和readObject方法,进行用户自定义的序列化和反序列化。

如果没有这样的方法,则默认调用是ObjectOutputStream的defaultWriteObject方法以及ObjectOutputStream的defaultReadObject方法。

用户自定义的writeObject和ReadObject方法可以允许用户控制序列化的过程,比如可以在序列化的过程中动态改变序列化的数值。

ArrayList底层是怎样通过Object数组完成存储

ArrayList底层是通过Object数组来完成数据存储的,但是这个数组被声明成了transient,说明在默认的序列化策略中并没有序列化数组字段。

ArrayList重写了writeObject和ReadObject方法,如下所示:

private void readObject(java.io.objectInputStream s)
    throw java.io.IOException,ClassNotFoundException {

    elementData = EMPTY_ELEMENTDATA;
    //Read in size,and any hiddn stuff
    s.defaultReadObject();

	//Read in capacity
	s.ReadInt();//ignored
	if(size > 0) {
	    //be like clon(),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();
		}
	}
}

private void writeObject(java.io.objectInputStream s)
    throw java.io.IOException {
    //Write out elememt count, and any hiddn stuff
    int expectedModCount = modCount;
    s.defaultWriteObject();

	//Write out size as capacity for behavioural campatibility with 		clon()

 	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 ConcurrentModifcationException();
	}
  }

知识拓展

为什么底层数组使用transient

ArrayList实际上是动态数组,每次在放满以后自动增长设定的长度值,如果数组自动增长长度设置为100,而实际只放了一个元素,那么会序列化99个null元素,为了保证在序列化的时候不会将这么多null同时进行序列化,ArrayList把元素数组设置为transient。

你可能感兴趣的:(Java集合类,开发语言,java,list)