一个类实现了Serializable 接口,而且使用了默认的序列化形式安全
若是没有认真考虑默认序列化形式是否合适,不要贸然接受线程
若是一个对象的物理表示法等同于逻辑内容,可能就适合于默认序列化形式对象
- 默认序列化,必须提供一个readObject 方法,来保证约束关系和安全性
若是一个对象的物理表示法与逻辑内容存在实质性区别时,默认序列化存在4个缺点:递归
- 该类导出API 永远束缚在该类的内部方表示法上
- 消耗过多空间
- 消耗过多时间
- 会引发栈溢出
- 默认序列化会对对象图进行一次递归遍历,很容易栈溢出
redaObject 和writeObject接口
- 实现这俩参数时,默认调用super.defaultReadObject 和 super.defaultWriteObject
- 若是全部成员变量都是transient(瞬时的),技术上不调用问题不大
- 可是仍是推荐调用下
- 可是不调用灵活性大增
散列表的序列化资源
- 同一JVM没法保证每次运行都同样
- 所以默认序列化会到来严重的bug
- 散列表的序列化和反序列化产生的对象,约束关系严重破坏
不管是否使用默认序列化形式同步
- 调用defaultWriteObject方法,transient实例域 都会被序列化
transient 域反序列化后会初始化默认值it
- 若是不能被任何任何transient域所接受,
- 能够实现redaObject 调用defaultReadObject 恢复为可接受的域
- 也能够将这些域延时到第一次被使用才真正初始化
不管何种序列化形式,若是读取整个对象状态的任何其余方法上强制任何同步,io
- 必须在对象序列化上强制这种同步
- 线程安全性考虑
- 注意锁的使用,规避资源排列死锁的危险
- 声明显式的序列化UID
- 这样避免序列化版本成为潜在不兼容根源
- 并且若是没有显式UID,会高成本产生一个序列化UID
- 若是但愿新版本可以接受现有序列化实例,就必须使用以前生成的旧版本UID
- 想要与现有版本不兼容,修改序UID便可
- 前版本实例反序列化会引起 InvalidClassException异常