一個類實現了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異常