# Serialization ###### tags: `Java` ### Introduce 意義:將一個物件表示為位元組序列 必要條件:實作java.io.Serializable介面 1. 實例變數若是參考型態且沒有被transient修飾,則也必須實作java.io.Serializable介面,否則序列化會Error 2. 在同一次序列化過程中同一個Object序列化多次,只有第一次會成功 JVM序列化演算法 : 1. 序列化後所有物件都會有一個編碼 2. 如果再次使用到序列化過的物件則只會輸出編碼 因此會造成序列化後修改資料,再序列化時不會更新後面修改的內容 ps:經測試同一次的定義為同一個ObjectOutputStream實體 3. 可透過修飾字**transient** 來決定不需要序列化的屬性 4. 自定義序列化 5. 類別變數不會被序列化 6. 反序列化必須有原始的class檔案 7. serialVersionUID用來判斷class檔案是否相同,如果不同會拋錯 版本號可自己指定,或者由JVM計算後指定,不同版本的JVM即使是相同的class也可能產生不同的UID。是否需要修改這個UID則可判斷實例變數是否有調整為依據,如果是修改方法、類別變數、transient變數則不需要調整 自定義序列化-透過override下列方法 private void writeObject(java.io.ObjectOutputStream out) throws IOException; private void readObject(java.io.ObjectIutputStream in) throws IOException,ClassNotFoundException; private void readObjectNoData() throws ObjectStreamException; 其他自定義序列化方法 ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException; 在序列化過程中較writeObject優先調用,並依照自定義方法**替換**掉原先要被序列化的物件 ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException; 在反序列化過程較readObject優先調用,並依照自定義方法**替換**掉反序列化的物件 ( 實現單例模式方法一) **Externalizable** 與Serializable不同之處為實作之後,必須實作 public void writeExternal(ObjectOutput out) throws IOException public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 即使有定義writeObject、readObject,在寫出、讀入時仍優先使用writeExternal、readExternal [https://juejin.im/post/5ce3cdc8e51d45777b1a3cdf](https://juejin.im/post/5ce3cdc8e51d45777b1a3cdf)[https://www.jianshu.com/p/d757e6da01d4](https://www.jianshu.com/p/d757e6da01d4) [https://www.cnblogs.com/binarylei/p/10987933.html](https://www.cnblogs.com/binarylei/p/10987933.html) [https://www.jianshu.com/p/3e3d86716f76](https://www.jianshu.com/p/3e3d86716f76)