什么是java序列化剃法,如何實現(xiàn)java序列化?或者請解釋Serializable接口的作用

一路鹰、概述

有一個Object持久化于緩存中贷洲,經(jīng)常需要變更字段(添加或刪除)收厨,每次做變更就要更改緩存表(擔(dān)心不兼容帶來問題,一直不確定哪些變更會來問題或引起什么樣的問題)优构,我希望實現(xiàn)一種序列化诵叁,當(dāng)變更或刪除字段時不需要變更緩存表,這需要達(dá)到兩個目的:1俩块、新的類訪問舊的緩存時沒問題黎休;2.舊的類訪問新的緩存時也沒問題。

二玉凯、Java序列化

java序列化提供了一個框架势腮,用來將對象編碼成字節(jié)流,并從字節(jié)流編碼中重新構(gòu)建的對象漫仆。將對象編碼為字節(jié)流稱之為序列化捎拯,反之將字節(jié)流重建成對象稱之為反序列化。

三盲厌、序列化實現(xiàn)方式

簡單示例

一個Person類署照,具有兩個屬性:name和age;

public class Personimplements Serializable {

????private Stringname ;// 姓名

? ? private int age ;// 年齡

? ? public Person(String name,int age){// 通過構(gòu)造方法賦值

? ? ? ? name = name ;

????????age = age ;

? ? ?}

? //getter ,setter方法

?}

生成一個Person的實例p,將期通過ObjectOutputStream寫入文件,并通過ObjectInputStream讀出來吗浩。這是一個完整的序列化/反序列化過程:ObjectOutputStream將p轉(zhuǎn)化成字節(jié)流寫入文件建芙,ObjectInputStream將從文件中讀出的字節(jié)流重新創(chuàng)建newPerson實例。

@Test

public void testSerializable()throws Exception {

File file =new File("p.dat");

Person p =new Person("xiaoming",10);

ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream(file));

oos.writeObject(p);

oos.close();

ObjectInputStream ois =new ObjectInputStream(new FileInputStream(file));

Object newPerson? = ois.readObject();

ois.close();

System.out.println(newPerson);

}

通過上面的過程懂扼,我們可以看出默認(rèn)的序列化機(jī)制對使用者而言是非常簡單的禁荸。序列化具體的實現(xiàn)是由ObjectOutputStream完成的;反序列化的具體實現(xiàn)是由ObjectInputStream完成的阀湿。

四赶熟、為何要實現(xiàn)Serializable

最重要的兩個原因是: 1、將對象的狀態(tài)保存在存儲媒體中以便可以在以后重新創(chuàng)建出完全相同的副本陷嘴; 2映砖、按值將對象從一個應(yīng)用程序域發(fā)送至另一個應(yīng)用程序域。 通俗的說:在分布式應(yīng)用中灾挨,你就得實現(xiàn)序列化邑退,如果你不需要分布式應(yīng)用,那就沒那個必要實現(xiàn)序列化涨醋。

Serializable是標(biāo)識類

Serializable是一個空接口瓜饥,沒有什么具體內(nèi)容,它的目的只是簡單的標(biāo)識一個類的對象可以被序列化浴骂。

五、哪些情況下需要序列化

當(dāng)你想把的內(nèi)存中的對象寫入到硬盤的時候宪潮;

當(dāng)你想用套接字在網(wǎng)絡(luò)上傳送對象的時候溯警;

當(dāng)你想通過RMI傳輸對象的時候趣苏;再稍微解釋一下:

比如說你的內(nèi)存不夠用了,那計算機(jī)就要將內(nèi)存里面的一部分對象暫時的保存到硬盤中梯轻,等到要用的時候再讀入到內(nèi)存中食磕,硬盤的那部分存儲空間就是所謂的虛擬內(nèi)存。在比如過你要將某個特定的對象保存到文件中喳挑,我隔幾天在把它拿出來用彬伦,那么這時候就要實現(xiàn)Serializable接口;

在進(jìn)行java的Socket編程的時候伊诵,你有時候可能要傳輸某一類的對象单绑,那么也就要實現(xiàn)Serializable接口;最常見的你傳輸一個字符串曹宴,它是JDK里面的類搂橙,也實現(xiàn)了Serializable接口,所以可以在網(wǎng)絡(luò)上傳輸笛坦。

如果要通過遠(yuǎn)程的方法調(diào)用(RMI)去調(diào)用一個遠(yuǎn)程對象的方法区转,如在計算機(jī)A中調(diào)用另一臺計算機(jī)B的對象的方法,那么你需要通過JNDI服務(wù)獲取計算機(jī)B目標(biāo)對象的引用版扩,將對象從B傳送到A废离,就需要實現(xiàn)序列化接口。

六礁芦、底層實現(xiàn)原理

先看下面代碼

Foo? myFoo = new Foo();?

myFoo .setWidth(37);?

myFoo.setHeight(70);

當(dāng)通過下面的代碼序列化之后蜻韭,MyFoo對象中的width和Height實例變量的值(37,70)都被保存到foo.ser文件中宴偿,這樣以后又可以把它從文件中讀出來湘捎,重新在堆中創(chuàng)建原來的對象。當(dāng)然保存時候不僅僅是保存對象的實例變量的值窄刘,JVM還要保存一些小量信息窥妇,比如類的類型等以便恢復(fù)原來的對象。

FileOutputStream fs = new FileOutputStream("foo.ser");?

ObjectOutputStream os = new ObjectOutputStream(fs);?

os.writeObject(myFoo);

那么大概步驟如下所示

1.Make a FileOutputStream? ? ?

`FileOutputStream fs = new FileOutputStream("foo.ser"); `

2.Make a ObjectOutputStream?

`ObjectOutputStream os =? new ObjectOutputStream(fs);? `

3.write the object

`os.writeObject(myObject1);?

os.writeObject(myObject2);?

os.writeObject(myObject3);? `

4.close the ObjectOutputStream

`os.close();`

serialVersionUID適用于Java的序列化機(jī)制娩践。

簡單來說活翩,Java的序列化機(jī)制是通過判斷類的serialVersionUID來驗證版本一致性的。在進(jìn)行反序列化時翻伺,JVM會把傳來的字節(jié)流中的serialVersionUID與本地相應(yīng)實體類的serialVersionUID進(jìn)行比較材泄,如果相同就認(rèn)為是一致的,可以進(jìn)行反序列化吨岭,否則就會出現(xiàn)序列化版本不一致的異常拉宗,即是InvalidCastException。

serialVersionUID有兩種顯示的生成方式:

一是默認(rèn)的1L,比如:private static final long serialVersionUID = 1L;

二是根據(jù)類名旦事、接口名魁巩、成員方法及屬性等來生成一個64位的哈希字段,比如:private static final long serialVersionUID = xxxxL;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姐浮,一起剝皮案震驚了整個濱河市谷遂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卖鲤,老刑警劉巖肾扰,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蛋逾,居然都是意外死亡集晚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門换怖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來甩恼,“玉大人,你說我怎么就攤上這事沉颂√趺” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵铸屉,是天一觀的道長钉蒲。 經(jīng)常有香客問我,道長彻坛,這世上最難降的妖魔是什么顷啼? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮昌屉,結(jié)果婚禮上钙蒙,老公的妹妹穿的比我還像新娘。我一直安慰自己间驮,他們只是感情好躬厌,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著竞帽,像睡著了一般扛施。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上屹篓,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天疙渣,我揣著相機(jī)與錄音,去河邊找鬼堆巧。 笑死妄荔,一個胖子當(dāng)著我的面吹牛泼菌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播懦冰,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼灶轰,長吁一口氣:“原來是場噩夢啊……” “哼谣沸!你這毒婦竟也來了刷钢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤乳附,失蹤者是張志新(化名)和其女友劉穎内地,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赋除,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡阱缓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了举农。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荆针。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖颁糟,靈堂內(nèi)的尸體忽然破棺而出航背,到底是詐尸還是另有隱情,我是刑警寧澤棱貌,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布玖媚,位于F島的核電站,受9級特大地震影響婚脱,放射性物質(zhì)發(fā)生泄漏今魔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一障贸、第九天 我趴在偏房一處隱蔽的房頂上張望错森。 院中可真熱鬧,春花似錦篮洁、人聲如沸涩维。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽激挪。三九已至,卻和暖如春锋叨,著一層夾襖步出監(jiān)牢的瞬間垄分,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工娃磺, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留薄湿,地道東北人。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像豺瘤,于是被迫代替她去往敵國和親吆倦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容