java序列化的方法_【Java常见序列化与反序列方法总结】
人和電腦在很多方面都是十分相似的,大腦可以看成電腦主機,五官/身體等表面器官就是顯示器、鼠標(biāo)等外設(shè)。這篇文章就是想把計算機跟人做類比YY一下序列化和反序列化的機制、用途。
如果你是初學(xué)者,心里肯定會問究竟什么是序列化/反序列化?其實我現(xiàn)在正在雨林木風(fēng)xp系統(tǒng)下載序列化而你正在反序列化:我在寫這篇博客的時候就是把大腦中的想法和思想經(jīng)過梳理寫成連續(xù)的文字,這就是序列化,而你在讀這篇博客的時候把這些整理過的文字讀進大腦形成你自己的思想,這個過程就是反序列化。 我們可以把大腦中的想法通過文字或聲音傳遞,這樣有“共同語言”的人就能將這些文字,聲音"讀"進大腦形成自己的思想,這就是 人與人之間“溝通、交流”的過程;為了防止記憶丟失我們通常會把自己的一些想法、知識以文字形式或聲音進行“保存”。? 計算機中序列化的定義是:把對象轉(zhuǎn)換成數(shù)據(jù)流以便在網(wǎng)絡(luò)上進行傳輸,或者將對象持久的存儲在某個地方的過程;相反,反序列化是接收數(shù)據(jù)流轉(zhuǎn)換成對應(yīng)的對象或從持久化存儲讀取數(shù)據(jù)轉(zhuǎn)換成對象的過程。簡單來說序列化就是用來做"有意義"的存儲或通信的。在Java中我們可以把一個對象序列化到網(wǎng)絡(luò)流,文件流,也可以序列化到字節(jié)數(shù)組等,然后可以從網(wǎng)絡(luò)流、文件流和字節(jié)數(shù)組等反序列化生成相應(yīng)的對象。
上面已經(jīng)提到序列化、反序列化主要用于對象的持久化存儲和遠(yuǎn)程通信。尤其在分布式系統(tǒng)中,應(yīng)用十分廣泛。
下面對Java默認(rèn)實現(xiàn)的序列化機制做一個由淺入深的介紹。
a.首先是序列化機制的目標(biāo),下面是官方說明:
1.簡單且易于擴展;
2.序列化形式能夠保證Java對象類型信息和安全屬性信息不丟失;
3.方便擴展支持marshalling和unmarshalling,這是實現(xiàn)遠(yuǎn)程對象的基礎(chǔ);
4.易于擴展,能方便實現(xiàn)Java對象的持久化;
5.針對不同類的對象提供可定制的持久化方式;
6.允許對象定制自己的外部表示形式;
b. java默認(rèn)提供的序列化機制:
1.序列化的基本步驟:
FileOutputStream fos = new FileOutputStream(outputFile)
1:ObjectOutputStream oos = new ObjectOutputStream(fos);
2:oos.writeObject(object);
3:oos.close();
第一步是創(chuàng)建一個對象輸出流oos,可以把對象序列化到文件、字節(jié)數(shù)組等,在構(gòu)造oos時賦予不同類型的流參數(shù)即可。
在ObjectOutputStream的JDK實現(xiàn)中可以看出,構(gòu)造oos對象時有安全管理器的校驗、設(shè)置流格式(包括設(shè)置流的頭信息:兩個MagicNumber)。
第二步就是寫入需要序列化的對象,這一步也是最為復(fù)雜的,包含了序列化機制的細(xì)節(jié)信息。
第三步關(guān)閉流。
第一步創(chuàng)建對象輸出流的時候,其實會初始化兩個Table:HandleTable和ReplaceTable,HandleTable主要是為了防止相同對象數(shù)據(jù)的重復(fù)寫入而設(shè)計。其中保存了原始對象到標(biāo)志此對象index的映射,這樣碰到重復(fù)的對象時寫入的實際上是這個index而非原始對象數(shù)據(jù)。還可以對原始序列化對象進行替換,ReplaceTable用來保存被替換對象的信息。
序列化機制里面有很多細(xì)節(jié)值得去挖掘:
比如:1.Java中的引用到底是什么,而序列化對象的時候如何消除重復(fù)對象的保存。
2.對于cycle reference的情況又是如何處理的。
后面將做更加詳細(xì)的分析。
很多商業(yè)項目用到數(shù)據(jù)庫、內(nèi)存映射文件和普通文件來完成項目中的序列化處理的需求,但是這些方法很少會依靠于Java序列化。本文也不是用來解釋序列化的,而是一起來看看面試中有關(guān)序列化的問題,這些問題你很有可能不了解。“Java序列化指的是將對象轉(zhuǎn)換程字節(jié)格式并將對象狀態(tài)保存在文件中,通常是.ser擴展名的文件。然后可以通過.ser文件重新創(chuàng)建Java對象,這個過程為返序列化”
Java序列化的API中提供了開發(fā)人員進行序列化對象的機制,通過Serializable和Externalizable接口。
一起看看這些問題:
1)Java中的Serializable接口和Externalizable接口有什么區(qū)別?
這個是面試中關(guān)于Java序列化問的最多的問題。我的回答是,Externalizable接口提供了兩個方法writeExternal()和readExternal()。這兩個方法給我們提供了靈活處理Java序列化的方法,通過實現(xiàn)這個接口中的兩個方法進行對象序列化可以替代Java中默認(rèn)的序列化方法。正確的實現(xiàn)Externalizable接口可以大幅度的提高應(yīng)用程序的性能。
2)Serializable接口中有借個方法?如果沒有方法的話,那么這么設(shè)計Serializable接口的目的是什么?
Serializable接口在java.lang包中,是Java序列化機制的核心組成部分。它里面沒有包含任何方法,我們稱這樣的接口為標(biāo)識接口。如果你的類實現(xiàn)了Serializable接口,這意味著你的類被打上了“可以進行序列化”的標(biāo)簽,并且也給了編譯器指示,可以使用序列化機制對這個對象進行序列化處理。
3)什么是serialVersionUID?如果你沒有定義serialVersionUID意味著什么?
SerialVersionUID應(yīng)該是你的類中的一個public static final類型的常量,如果你的類中沒有定義的話,那么編譯器將拋出警告。如果你的類中沒有制定serialVersionUID,那么Java編譯器會根據(jù)類的成員變量和一定的算法生成用來表達(dá)對象的serialVersionUID ,通常是用來表示類的哈希值(hash code)。結(jié)論是,如果你的類沒有實現(xiàn)SerialVersionUID,那么如果你的類中如果加入或者改變成員變量,那么已經(jīng)序列化的對象將無法反序列化。這是以為,類的成員變量的改變意味這編譯器生成的SerialVersionUID的值不同。Java序列化過程是通過正確SerialVersionUID來對已經(jīng)序列化的對象進行狀態(tài)恢復(fù)。
總結(jié)
以上是生活随笔為你收集整理的java序列化的方法_【Java常见序列化与反序列方法总结】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java引入依赖aar,如何将JAR依赖
- 下一篇: java包含关系图_Java——Spri