1. 为什么elementData用transient修饰?
      1. private void writeObject(java.io.ObjectOutputStream s)
      2. throws java.io.IOException{
      3. // Write out element count, and any hidden stuff
      4. int expectedModCount = modCount;
      5. s.defaultWriteObject();
      6. // Write out size as capacity for behavioural compatibility with clone()
      7. s.writeInt(size);
      8. // Write out all elements in the proper order.
      9. for (int i=0; i<size; i++) {
      10. s.writeObject(elementData[i]);
      11. }
      12. if (modCount != expectedModCount) {
      13. throw new ConcurrentModificationException();
      14. }
      15. }
    1. private void readObject(java.io.ObjectInputStream s)
    2. throws java.io.IOException, ClassNotFoundException {
    3. elementData = EMPTY_ELEMENTDATA;
    4. // Read in size, and any hidden stuff
    5. s.defaultReadObject();
    6. // Read in capacity
    7. s.readInt(); // ignored
    8. if (size > 0) {
    9. // be like clone(), allocate array based upon size not capacity
    10. ensureCapacityInternal(size);
    11. Object[] a = elementData;
    12. // Read in all elements in the proper order.
    13. for (int i=0; i<size; i++) {
    14. a[i] = s.readObject();
    15. }
    16. }
    17. }

    ArrayList在序列化的时候会调用writeObject,直接将size和element写入ObjectOutputStream;反序列化时调用readObject,从ObjectInputStream获取size和element,再恢复到elementData。

    为什么不直接用elementData来序列化,而采用上诉的方式来实现序列化呢?原因在于elementData是一个缓存数组,它通常会预留一些容量,等容量不足时再扩充容量,那么有些空间可能就没有实际存储元素,采用上诉的方式来实现序列化时,就可以保证只序列化实际存储的那些元素,而不是整个数组,从而节省空间和时间。

    1. 为什么是两个private的方法
      ObjectOutputStream使用了反射来寻找是否声明了这两个方法。因为ObjectOutputStream使用getPrivateMethod,所以这些方法不得不被声明为priate以至于供ObjectOutputStream来使用。

    参考
    (20条消息) 序列化writeObject与readObject_MrMoving的博客-CSDN博客