ArrayList的elementData属性为什么用了transient修饰后,依然可以序列化,这样的好处?
通过ArrayList源码可以看出ArrayList实现了Serializable接口,但是elementData数组确是transient修饰的。
序列化即可以把内存里面的内容保存到磁盘上。transient表示它修饰的变量不会被保存到磁盘中去。
下面来探讨一下为什么?
先看一下下面的代码:
String[] a=new String[4];
a[0]="liu";
a[2]="tt";
ObjectOutputStream outputStream=new ObjectOutputStream(new FileOutputStream("C:/Users/tt/Desktop/tt.txt"));
outputStream.writeObject(a);
outputStream.flush();
outputStream.close();
ObjectInputStream inputStream=new ObjectInputStream(new FileInputStream("C:/Users/tt/Desktop/tt.txt"));
String[] b=(String[]) inputStream.readObject();
inputStream.close();
System.out.println(Arrays.toString(b));
定义了一个长度为4的数组,但是只赋值了两个元素,然后进行序列化,再反序列化读出,结果:
说明它把整歌数组都序列化了,即使有的地方没有元素,让我们来想一下,如果定义的数组长度很长,但是实际存储的元素并不多,进行序列化反序列化时就会很浪费时间和空间。
ArrayList中的elementData数组是存储元素的数组缓冲区,它的长度要大于实际存储的元素的个数。因此把elementData声明为transi,来告诉虚拟机这个数组的序列化,我自己来,然后自己重写了writeObject和readObject方法。
可以看到,writeobject中,在写入时,i<size,size是实际存储的元素的长度,因此相当于是序列化实际存储元素的长度而不是整个数组,节省了空间和时间的花销。