更新時間:2022-12-13 12:50:02 來源:動力節(jié)點(diǎn) 瀏覽1169次
Java序列號之Java序列化是什么?動力節(jié)點(diǎn)小編來告訴大家。
序列化:將對象寫入到IO流中
反序列化:從IO流中恢復(fù)對象
1.序列化機(jī)制允許將實(shí)現(xiàn)序列化的Java對象轉(zhuǎn)換位字節(jié)序列,這些字節(jié)序列可以保存在磁盤上。
2.通過網(wǎng)絡(luò)傳輸,以達(dá)到以后恢復(fù)成原來的對象。
3.序列化機(jī)制使得對象可以脫離程序的運(yùn)行而獨(dú)立存在。
1.所有可在網(wǎng)絡(luò)上傳輸?shù)膶ο蠖急仨毷强尚蛄谢摹?/p>
2.所有需要保存到磁盤的java對象都必須是可序列化的。
所以基本上每個javaBean類都實(shí)現(xiàn)Serializeable接口。
實(shí)現(xiàn)Serializable接口或者Externalizable接口之一。
1.序列化步驟:
步驟一:創(chuàng)建一個ObjectOutputStream輸出流;
步驟二:調(diào)用ObjectOutputStream對象的writeObject輸出可序列化對象。
2.反序列化步驟:
步驟一:創(chuàng)建一個ObjectInputStream輸入流;
步驟二:調(diào)用ObjectInputStream對象的readObject()得到序列化的對象。
3.注意:引用類型類成員
如果一個可序列化的類的成員不是基本類型,也不是String類型,那這個引用類型也必須是可序列化的;否則,會導(dǎo)致此類不能序列化。
4.注意:同一對象序列化多次的機(jī)制
【同一對象序列化多次,并不會將此對象序列化多次得到多個對象。】原因如下:(Java序列化算法)
所有保存到磁盤的對象都有一個序列化編碼號
當(dāng)程序試圖序列化一個對象時,會先檢查此對象是否已經(jīng)序列化過,只有此對象從未(在此虛擬機(jī))被序列化過,才會將此對象序列化為字節(jié)序列輸出。
如果此對象已經(jīng)序列化過,則直接輸出編號即可。
5.潛在的問題:
如果序列化一個可變對象(對象內(nèi)的內(nèi)容可更改)后,更改了對象內(nèi)容,再次序列化,并不會再次將此對象轉(zhuǎn)換為字節(jié)序列,而只是保存序列化編號。
所以,比較反序列化后,兩個對象更改的內(nèi)容屬性,任然是相同的。
6.自定義序列化:
(1)使用transient關(guān)鍵字選擇不需要序列化的字段。對于引用類型,值是null;基本類型,值是0;boolean類型,值是false。
(2)通過重寫writeObject與readObject方法,可以自己選擇哪些屬性需要序列化, 哪些屬性不需要。
(3)如果writeObject使用某種規(guī)則序列化,則相應(yīng)的readObject需要相反的規(guī)則反序列化,以便能正確反序列化出對象。這里展示對名字進(jìn)行反轉(zhuǎn)加密。
(4)當(dāng)序列化流不完整時,readObjectNoData()方法可以用來正確地初始化反序列化的對象。
(5)徹底的自定義序列化:
1)writeReplace:在序列化時,會先調(diào)用此方法,再調(diào)用writeObject方法。此方法可將任意對象代替目標(biāo)序列化對象
2)readResolve:反序列化時替換反序列化出的對象,反序列化出來的對象被立即丟棄。此方法在readeObject后調(diào)用。
3)readResolve常用來反序列單例類,保證單例類的唯一性。
1.通過實(shí)現(xiàn)Externalizable接口,必須實(shí)現(xiàn)writeExternal、readExternal方法。
注意1:Externalizable接口不同于Serializable接口,實(shí)現(xiàn)此接口必須實(shí)現(xiàn)接口中的兩個方法實(shí)現(xiàn)自定義序列化,這是強(qiáng)制性的;
注意2:特別之處是必須提供pulic的無參構(gòu)造器,因?yàn)樵诜葱蛄谢臅r候需要反射創(chuàng)建對象。
Serializable:系統(tǒng)自動存儲必要的信息、易于實(shí)現(xiàn),只需要實(shí)現(xiàn)該接口、性能略差
Externalizable:程序員決定存儲哪些信息、必須實(shí)現(xiàn)接口內(nèi)的兩個方法、性能略好
1.作用:
反序列化必須擁有class文件,但隨著項(xiàng)目的升級,class文件也會升級為保證升級前后的兼容性:
java序列化提供了一個serialVersionUID 的序列化版本號,只有版本號相同,即使更改了序列化屬性,對象也可以正確被反序列化回來。
2.不指定版本號的隱患:
序列化版本號如果不指定,JVM會根據(jù)類信息自己計算一個版本號,這樣隨著class的升級,就無法正確反序列化;
不指定版本號另一個明顯隱患是,不利于jvm間的移植,可能class文件沒有更改,但不同jvm可能計算的規(guī)則不一樣,這樣也會導(dǎo)致無法反序列化。
相關(guān)閱讀
初級 202925
初級 203221
初級 202629
初級 203743