考虑自定义的序列化模式(75)

一个类实现了Serializable 接口,而且使用了默认的序列化形式安全

  • 没法摆脱该实现,永远牵制该类的序列化形式

若是没有认真考虑默认序列化形式是否合适,不要贸然接受线程

若是一个对象的物理表示法等同于逻辑内容,可能就适合于默认序列化形式对象

  • 默认序列化,必须提供一个readObject 方法,来保证约束关系和安全性

若是一个对象的物理表示法与逻辑内容存在实质性区别时,默认序列化存在4个缺点:递归

  1. 该类导出API 永远束缚在该类的内部方表示法上
    • 不方便之后扩展
  2. 消耗过多空间
  3. 消耗过多时间
  4. 会引发栈溢出
    • 默认序列化会对对象图进行一次递归遍历,很容易栈溢出

redaObject 和writeObject接口

  • 实现这俩参数时,默认调用super.defaultReadObject 和 super.defaultWriteObject
    • 若是全部成员变量都是transient(瞬时的),技术上不调用问题不大
    • 可是仍是推荐调用下
    • 可是不调用灵活性大增

散列表的序列化资源

  • 同一JVM没法保证每次运行都同样
  • 所以默认序列化会到来严重的bug
  • 散列表的序列化和反序列化产生的对象,约束关系严重破坏

不管是否使用默认序列化形式同步

  • 调用defaultWriteObject方法,transient实例域 都会被序列化

transient 域反序列化后会初始化默认值it

  • 若是不能被任何任何transient域所接受,
    • 能够实现redaObject 调用defaultReadObject 恢复为可接受的域
    • 也能够将这些域延时到第一次被使用才真正初始化

不管何种序列化形式,若是读取整个对象状态的任何其余方法上强制任何同步,io

  • 必须在对象序列化上强制这种同步
  • 线程安全性考虑
  • 注意锁的使用,规避资源排列死锁的危险
  • 声明显式的序列化UID
    • 这样避免序列化版本成为潜在不兼容根源
    • 并且若是没有显式UID,会高成本产生一个序列化UID
    • 若是但愿新版本可以接受现有序列化实例,就必须使用以前生成的旧版本UID
      • 想要与现有版本不兼容,修改序UID便可
      • 前版本实例反序列化会引起 InvalidClassException异常
相关文章
相关标签/搜索