ArrayList可以被持久化吗 虽然他继承了序列化接口,但ArrayList的内容都是存储在
private transient Object[] elementData;
中的,可是这个数组是个瞬态变量,如果ArrayList能被序列化,可是内容都保存在elementData中,elementDate不能被持久化,那ArrayList又怎么能持久化呢?好像jdk中不只ArrayList是这样,连Map、Set的实现也是这样,用瞬态的变量保存数据,而类本身实现序列化接口,这个我不太明白
private transient Object[] elementData;
中的,可是这个数组是个瞬态变量,如果ArrayList能被序列化,可是内容都保存在elementData中,elementDate不能被持久化,那ArrayList又怎么能持久化呢?好像jdk中不只ArrayList是这样,连Map、Set的实现也是这样,用瞬态的变量保存数据,而类本身实现序列化接口,这个我不太明白
这样就必须把每个类型为ArrayList的成员设成transient的,会比较麻烦
并且,该对象所持有的其他对象也需要 直接或间接地 实现java.io.Serializable接口;
否则将引起异常或不能正确地反序列化。
并且,该对象所持有的其他对象也需要 直接或间接地 实现java.io.Serializable接口;
那么private transient Object[] elementData;
是ArrayList持有的对象,那他有被序列化吗?transient难道不是瞬态的吗?
在序列化的时候会调用writeObject方法。 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{
//...
s.defaultWriteObject();
s.writeInt(elementData.length);
for (int i=0; i<size; i++)
s.writeObject(elementData[i]);
//...
}
ObjectOutputStream oos;
oos=new ObjectOutputStream(new FileOutputStream(myObjectFile));
ArrayList<Integer> a=new ArrayList<Integer>();
a.add(1);
a.add(2);
oos.writeObject(a);
oos.close();虽然成功的把ArrayList持久化了,可是并没有调用ArrayList的writeObject()方法,因为他是私有的,别不能调用,可是还是实现持久化了, 不太明白啊
现在明白怎么回事了,但是我还有点问题
他为什么要把它持有的对象设为瞬态的,瞬态只有在持久化时才起作用,我觉得没太大必要这样,可能是有什么性能的考量,但是不知道为什么
我把jdk相关代码又看了一遍,觉得ArrayList类实现writeObject方法的原因并发有关
完整代码是这样的:private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{
int expectedModCount = modCount;
s.defaultWriteObject();
s.writeInt(elementData.length);
for (int i=0; i<size; i++)
s.writeObject(elementData[i]); if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}modCount是从AbstractList继承来的一个protected字段,主要用来在并发环境下检查List有没有被修改。
如果在序列化的过程中列表被另一个线程修改了,那么就抛出异常。如果只是声明了Serializable,但是不实现writeObject,就不会有这种检查。当然,手工实现writeObject方法,仍然可以不将elementData设为瞬时的,而是通过s.defaultWriteObject()将数组写入。但是我猜想,既然反正要手工实现writeObject,不如手动将所有元素依次写入,这样可以少一层函数调用(数组的defaultWriteObject显然也是那样一个循环),提高效率;另一方面,也是为了遵循“依据逻辑而不是底层实现”的原则,提高了灵活性,见Effective Java条款之Consider using a custom serialized form。