Serializable 使用心得

Posted on Aug 1, 2006
  1. writeObject 和 readObject 必须是 private 的, 否则不会被调用.

  2. Object 的 field 的读写顺序, 遵循先进先出的原则.

  3. 从 ObjectInputStream 中读 Object 的原理是: 先从流中读出每个元素的类型, 例如是数组, String 还是Object 等, 如果是 Object, 就继续从流中读取这个类的描述信息, load 这个类, 然后取这个类的第一个非 Serializable 的父类的 public 无参数构造函数, 通过构造函数创建实例, 最后调用 readObject 或 defaultReadObject 为这个实例赋值.

  4. 从 3 可以看出, 在从 ObjectInputStream 中读出的 Object 时, 和写进去的不是同一个 Object.

  5. 不用怀疑, JVM 有办法调用你的类的 private 方法和父类的 default 构造函数.

  6. 序列化写一个类的 object, 序列化读的程序的 classpath 中也要有这个类, 否则读时抛出 ClassNotFound.

  7. 序列化的这个类的第一个非 Serializable 的父类, 必须有一个 public 的, 无参数的构造函数.

  8. 具体细节可以参考 JDK 源码中的 java.io.ObjectInputStream 和 java.io.ObjectStreamClass.

  9. 总之, 序列化读就是创建一个空 Obejct, 然后通过 readObject 赋值的过程.

  10. 默认的序列化, 会同时序列化 static 的 field, 就如同普通的 field一样.

  11. 序列化写时, 同一个对象, 2 次写入, 不论是直接写入, 还是做为其他 object 的一个成员变量被连带写入的, 实际上只是写了一次, 另一次只是在 stream 做了一个标记. 序列化读时, 读 2 次, 返回的实际上也是一个对象.

  12. 将 2 个互相引用的对象序列化, 根据上面的一个对象只会被序列化一次的原则, 因此实际上这 2 个对象也只是分别被写入一次.

  13. 向 ObjectOutputStream 中写一个 Object, 却从 ObjectInputStream 中连续读两次, 第二次出 EOFException.

  14. 只有写时用了 writeInt 等方法, 读时才能用 readInt, 否则出 EOFException.

  15. Externalizable 与 Serializable 不同, 其反序列化时, 会通过这个类的默认构造函数来构造实例, 随后再调用 readExternal, 因此如果这个类没有默认构造函数, 或默认构造函数不是 public 的, 那么, 就会出异常.