Serializable序列化的簡要說明
一、 持久化的簡單介紹:
“持久化”意味着對象的“生存時間”并不取決于程式是否正在執行——它存在或“生存”于程式的每一次調用之間。通過序列化一個對象,将其寫入磁盤,以後在程式再次調用時重新恢複那個對象,就能圓滿實作一種“持久”效果。
二、 語言裡增加了對象序列化的概念後,可提供對兩種主要特性的支援:
遠端方法調用(RMI)使本來存在于其他機器的對象可以表現出好象就在本地機器上的行為。将消息發給遠端對象時,需要通過對象序列化來傳輸參數和傳回值。
使用一個Java Bean 時,它的狀态資訊通常在設計期間配置好。程式啟動以後,這種狀态資訊必須儲存下來,以便程式啟動以後恢複;具體工作由對象序列化完成。
三、 Serializable的一些說明:
對象的序列化處理非常簡單,隻需對象實作了Serializable 接口即可(該接口僅是一個标記,沒有方法)
序列化的對象包括基本資料類型,所有集合類以及其他許多東西,還有Class 對象
對象序列化不僅儲存了對象的“全景圖”,而且能追蹤對象内包含的所有句柄并儲存那些對象;接着又能對每個對象内包含的句柄進行追蹤
使用transient關鍵字修飾的的變量,在序列化對象的過程中,該屬性不會被序列化。
四、 序列化的步驟:
首先要建立某些OutputStream對象:OutputStream outputStream = new FileOutputStream("output.txt")
将其封裝到ObjectOutputStream對象内:ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
此後隻需調用writeObject()即可完成對象的序列化,并将其發送給OutputStream:objectOutputStream.writeObject(Object);
最後不要忘記關閉資源:objectOutputStream.close(), outputStream .close();
五、 反序列化的步驟:
首先要建立某些OutputStream對象:InputStream inputStream= new FileInputStream("output.txt")
将其封裝到ObjectInputStream對象内:ObjectInputStream objectInputStream= new ObjectInputStream(inputStream);
此後隻需調用writeObject()即可完成對象的反序列化:objectInputStream.readObject();
最後不要忘記關閉資源:objectInputStream.close(),inputStream.close();
Serializable序列化的代碼執行個體
項目結構如下,源代碼下載下傳見huhx友情連結:
一、 首先我們建立一個Man類,實作了Serializable接口,用于Person類的測試:
二、 我們再建立一個Person類,用于序列化:
三、 編寫一個包含main方法的測試類:MainTest,它的writeSerializableObject用于序列化對象:
四、 測試類MainTest,它的readSerializableObject用于反序列化對象:
五、 在Main方法添加以上兩個方法的運作,結果如下:
在Person類中包含Man的引用,當Person被序列化的時候,從結果可以知道Man也被序列化了
writeObject方法可以傳入String,是因為String首先是一個類,其次它也是實作了Serializable接口的
Person類中的age字段是transient,從列印結果可以看到,序列化Person person = new Person(man, "劉力", 21)對象時,age沒有進行序列化。如果transient修飾的Object類型的,那麼列印的結果将會是null
Externalizable序列化的代碼執行個體
首先我們看一下Externalizable的定義:繼承了Serializable
一、 同樣的我們先建立一個實作了Externalizable的User類:重寫裡面兩個方法readExternal和writeExternal
二、 在MainTest中加入方法writeExternalizableObject,用于序列化對象User
三、 在MainTest中加入方法writeExternalizableObject,用于反序列化對象User
四、 在Main方法添加以上兩個方法的運作,結果如下:
首先User user = new User("huhx", 22);執行了User的含參構造函數
當執行到writeObject(user);方法時,由于User實作了Externalizable接口,是以它的writeExternal會執行,
在User中的readExternal方法中調用了ObjectInput的readObject方法,在這個方法中通過反射機制建立User的執行個體,調用了User的無參構造函數。
然後在readObject方法執行的時候,同樣會先執行User類的readExternal方法。這個會在後續源代碼分析時講到