




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、什么是序列化java'p的序列化(serialization)機(jī)制能夠?qū)⒁粋€(gè)實(shí)例對(duì)象的狀態(tài)信息寫入到一個(gè)字節(jié)流 中,使其町以通過socket進(jìn)行傳輸、或者持久化存儲(chǔ)到數(shù)據(jù)庫或文件系統(tǒng)中;然后在需耍 的時(shí)候,可以讀取字節(jié)流中的信息來重構(gòu)一個(gè)相同的對(duì)象。序列化機(jī)制在java屮有看廣泛 的應(yīng)用,ejb、rmi、hessian等技術(shù)都是以此為基礎(chǔ)的。so,序列化一般用于以下-場(chǎng)景:1:永久性保存對(duì)彖,保存對(duì)彖的字節(jié)序列到本地文件或者數(shù)據(jù)庫中2:通過序列化以字節(jié)流的形式使對(duì)彖在網(wǎng)絡(luò)中進(jìn)行傳遞和接收;3:通過序列化在進(jìn)程間傳遞對(duì)象。接下來我們將從序列化機(jī)制原理等方面進(jìn)行剖析如何序列化一個(gè)對(duì)象類通過
2、實(shí)現(xiàn)java.io.serializable接口以啟用其序列化功能。耒實(shí)現(xiàn)此接口的類將無法 使其任何狀態(tài)序列化或反序列化??尚蛄谢惖乃凶宇愋捅旧矶际强尚蛄谢摹P蛄谢?口沒有方法或字段,僅用于標(biāo)識(shí)可序列化的語義。1:我們先來看看一個(gè)例子將對(duì)彖序列化為一個(gè)字節(jié)流10public class testserial implements serializable 1112public byte version = 10;13public byte count= 0;1415日public void f()16 system, out .printin (rrhellon);17 1819202
3、122232425272830313233343536373839public static void ir.ain (string args ) throws ioexception exception flleoutputstrearr. f os = new fileoutputstrearr. (riterr.p . outn);objecroutputstreair. oos = new objectoutputstreair.(fos);testserial ts = new testserial ();oos.writeobject(oosflush();oosclose ();
4、fllelnputstrearr. f is = new filelnputstrearr. (nterr.p . outn);objectinputstreair. oin = new objectlnputstreair.(fis);testserial tsl = (testserial) oin-readobject();system.out.printin(nver3ion=n + tsl.version);40 42 我們將對(duì)象序列化并輸出。objectoutputstream能把object輸出成byte流。上圖 顯示的20 tj -26行我們將byte流暫時(shí)存儲(chǔ)到temp.ou
5、t文件里。而在33行39行,我們利用反序列化,根據(jù)字節(jié)流重建對(duì)象。從上面代碼中,我們不難看出,序列化和反序列化的倆個(gè)主耍類:objectoutputstream.objectinputstream o序列化后的內(nèi)容通過上面的例子我們知道,對(duì)象被序列化存在至文件temp.out屮,我們可以通過工具ultraedit以16進(jìn)制方式打開該文件,看看它里而是以什么樣的形式存在組織我們的對(duì)彖的。ac ed0005737200157465737453657269;.sz.testseri61 6c2e5465737453657269616cae18b4;&:ltestserial?be of043
6、9ec020002420005636f756e74;?9?bcount42 000776657273696f6e78700064;審versionxpd毎一行分號(hào)后血的內(nèi)容都是前面16進(jìn)制碼的注釋。對(duì)于這些我們先隨意yy下,這些內(nèi)容的組織方式應(yīng)該是:1:對(duì)象類型描述2:對(duì)彖屬性類型描述3対象屬性值現(xiàn)在我們將以一個(gè)全血的例子來說明該問題:代碼ascript view plaincopy1. class parent implements serializable 2. int parentversion = 10;3. 4. class contain implements serializab
7、le 5int containversion = 11;|67. public class serialtest extends parent implements serializable 8. intversion = 66;9. contain con二 new contain();10.public int getversion() 11.return version;12.13.public static void mai“(string args) throws ioexception 14.fileoutputstrearn fos = new fileoutputstream(
8、"tempjl.out");15objectoutputstream oos = new objectoutputstream(fos);16.serialtest st = new serialtest();17.ooswriteobject(st);18.oos-flush();19.oos-close();20.21. temp_1 .out文件內(nèi)容如h:01 2 3 4$ $ ?1? ? d 4oooooooohaced0005737200157465737453657269.sr.testseriooooooloh616c2e53657269616c5465737
9、405f5c8al.serialtest踩00000020hbd0145443d0200024900077665727369?ed=.i.versi00000030h6f6e4c0003636f6e7400144c74657374onl.cont.ltest00000040b53657269616c2f636f6e74616 96e3b78serial/contain;x00000050b7200117465737453657269616c2e7061r.testserial.pa00000060b72656e749d58b50dd205979302000149rent排.i00000070h
10、000d706172656e74566572736 96f6e78.parentversionx00000080h700000000a0000004273720012746573pbsr tes00000090b7453657269616c2e636f6e7461696e2etserialcontain.ooooooaohf62da6f7ase69e02000149000e636f6e?兒?.i.conooooooboh7461696e56657273696f6e7870000000tainversionxp.oooooocoh0b先對(duì)上而圖簡(jiǎn)單注w f: oooooooh-oooooocoh
11、表示行號(hào)(我們一次可以稱為第一行,第二行),0f表示列;行后而的文字表示對(duì)這行16進(jìn)制的解釋。我們來仔細(xì)看看這些字節(jié)都是些說明東西。第一行的:0列4列1. aced:stream_magic.聲明使用了序列化協(xié)議.可以理解為實(shí)現(xiàn)了 serializable 類2.00 05: stream_version.序歹ij化協(xié)議版木.3.0x73: tc_object.聲明這是一個(gè)新的對(duì)象.因此第一步存儲(chǔ)的就是序列化的描述。二 輸出serialtest類的描述:第一行的5列到三行的7列1: 4.0x72: tc_classdesc聲明這里開始一個(gè)新 class。2. 00 15: class 名字的長(zhǎng)
12、度(包括 package 名稱:如本例就是:testserial.serialtest; 正好21的長(zhǎng)度,16進(jìn)制表示就為15 了).3. 74 65 73 74 53 65 72 69 61 6c 2e 53 65 72 69 61 6c 54 65 73 74 表示 testserial/serialtest 類的全限定名4. 第二行的d列到3行的4列表示:serialversionuid,序列化id,如果沒有指定,則會(huì)由算法隨機(jī)生成一個(gè)8byte的id.5. 0x02:標(biāo)記號(hào).該值聲明該對(duì)彖支持序列化。6. 00 02:該類所包含的域個(gè)數(shù)。三:接下來,輸出其中的一個(gè)域(一次從上到下父類到
13、子類),int version=66; 3行8列4 行1列1.0x49:域類型49代表t,也就是int.2. 00 07:域名字的長(zhǎng)度.3. 76 65 72 73 69 6f 6e: version,域名字描述.四:另外一個(gè)域,contain con = new contain();ii個(gè)有點(diǎn)特殊,是個(gè)對(duì)象。?描述對(duì)象類 型引用時(shí)需要使用jvm的標(biāo)準(zhǔn)對(duì)象簽名表示法,4行2列5行f列1:0x4c:域的類型.2:00 03:域名字長(zhǎng)度.3:63 6f 6e:域名字描述,con4:0x74: tc_string.代表一個(gè) new string.用 string 來引用對(duì)象。5:00 14:該 st
14、ring 長(zhǎng)度.既:ltestserial/contain 的長(zhǎng)度6:4彳亍b-5彳亍e歹ij: ltestserial/contain;, jvm的標(biāo)準(zhǔn)對(duì)象簽名表示法.6:0x78: tc.endblockdata,對(duì)象數(shù)據(jù)塊結(jié)束的標(biāo)志五:parent類描述了 6行的0列到7行的e列1:0x72: tc_classdesc.聲明這個(gè)是個(gè)新類.2:00 11:類名長(zhǎng)度.3:6 行 3 列7 行 3 歹ij: testserial.parent,類名描述。4:7 行 4 列7 行 b 列:serialversionuid,序列化 id.5:0x02:標(biāo)記號(hào).該值聲明該對(duì)象支持序列化.6:00 0
15、1:類中域的個(gè)數(shù).六:parent類的域描述,int parentversion=100 7行f列9行0列1:0x49:域類型.49代表t,也就是int.2:00 0d:域名字長(zhǎng)度.3:8行2列-8行e歹ij: parentversion,域名字描述。4:0x78: tc_endblockdata,対象塊結(jié)束的標(biāo)志。5:0x70: tc_null,說明沒有其他超類的標(biāo)志。七:到此為止,算法已經(jīng)對(duì)所有的類的描述都做了輸出。下一步就是把實(shí)例對(duì)象的實(shí)際值 輸出了。這時(shí)候是從parent class的域開始的,9行一列9行4列00 00 00 0a: 10, parentversion 域的值.八:還
16、有serialtest類的域:9行5列9行8列00 00 00 42: 66, version 域的值.九:再往后的bytes比較有意思,算法需要描述contain類的信息1: 0x73: tcjdbject,聲明這是一個(gè)新的對(duì)彖.2:0x72: tc_classdesc 聲明這里開始一個(gè)新 class.3:00 12:類名的長(zhǎng)度.4:9 行 d 列10 行 e 列:testserial.contain,類名描述.5:10 行 f 列11 行 6 列:serialversionuid,序列化 id.6: 0x02: various flags.標(biāo)記號(hào).該值聲明該對(duì)象支持序列化7:00 01 :
17、類內(nèi)的域個(gè)數(shù)。十:輸出 contain 的唯一的域描述,int containversio1:0x49:域類型.49代表t,也就是int.2:00 0e:域名字長(zhǎng)度.3:63 6f 6e 74 61 69 6e 56 65 72 73 69 6f 6e: containversion,域名字描述. 4:0x78: tc_endblockdata對(duì)象塊結(jié)束的標(biāo)志.十一:這時(shí),序列化算法會(huì)檢查contain是否有超類,如果有的話會(huì)接著輸出。 0x70:tc_null,沒有超類了。十二:最后,將contain類實(shí)際域值輸出。00 00 00 0b: 11, containversion 的值.總結(jié)下
18、序列化后二進(jìn)制流中按哪些順序存儲(chǔ)哪些內(nèi)容:當(dāng)前類描述當(dāng)前類屈性描述超類描述超類屬性描述(如果超類還有超類,則依次遞歸)超類屈性值描述子類屬性值描述既是:類描述是從下到上,類屈性描述是從上到下。倆個(gè)是反著來的。transient和static的類變量的序列化我們現(xiàn)在回過去看看代碼11。然后修成下:如下一-代碼12java view plain copy1-省略前面:2.3.public class serialtest extends parentimplements serializable 8-9.10-11.12.intversion= 66;public static in
19、t teststatic= 1;public transient int testtransient 二 2;containcon=new contain();public int getversion() 13. return version;14.類serialtest新増了倆個(gè)變量public static int teststatic = 1; public transient int testtransient = 2;然后再看看重新生成的temp_1 .out文件內(nèi)容,我們驚奇發(fā)現(xiàn)文件內(nèi)容和沒有新增變量z前 是一模一樣的。so,我們推理static和transient變量被序列化的
20、時(shí)候,并不會(huì)序列化?,F(xiàn)在哥們我用別人 的總結(jié)來總結(jié)白己的序列化時(shí),類的所有數(shù)據(jù)成員應(yīng)可序列化除了聲明為transient或static的成員。將 變量聲明為transient告訴jvm我們會(huì)負(fù)責(zé)將變?cè)蛄谢?。將?shù)據(jù)成員聲明為transient 后,序列化過程就無法將其加進(jìn)對(duì)象字節(jié)流中,沒有從transient數(shù)據(jù)成員發(fā)送的數(shù)據(jù)。后 面數(shù)據(jù)反序列化時(shí),要重建數(shù)據(jù)成員(因?yàn)樗穷惗x的一部分),但不包含任何數(shù)據(jù), 因?yàn)檫@個(gè)數(shù)據(jù)成員不向流中寫入任何數(shù)據(jù)。記住,對(duì)象流不序列化static或transient。我 們的類要用writeobject()與readobject()方法以處理這些數(shù)據(jù)成員。使用
21、writeobject() 與readobject()方法時(shí),還要注意按寫入的順序讀取這些數(shù)據(jù)成員那對(duì)于這些問題,我們?cè)撊绾芜M(jìn)行序列化和反序列化呢?簡(jiǎn)單,也就是說我們耍對(duì)這倆個(gè)類型的變量單獨(dú)處理,怎么辦?就是在出現(xiàn)這類變量的所屬類中增加倆個(gè)方法java view plain copy1. private void writeobject(java.io.objectoutputstrearn out) throws ioexception2. private void readobject(java.io.objectinputstream in) throws ioexception, cl
22、 assnotfoundexception;而對(duì)應(yīng)于我們的類中添加的方法就是java view plain copy..3.14.public class serialtest extends parent implements serializable /省略private void writeobject(objectoutputstream out) throws ioexception out-defaultwriteobject();outwritelnt(thisteststatic);outhis.testtransient);p
23、rivate void readobject(objectinputstream in) throws ioexception classn otfoundexception indefaultreadobject();this.teststatic = in.readlnt();t his. testtw nsie nt = in .readl nt();當(dāng)objectoutputstream對(duì)一個(gè)serialtest對(duì)象進(jìn)行序列化時(shí),如果該對(duì)象具有 writeobject()方法,那么就會(huì)執(zhí)行這一方法,否則就按默認(rèn)方式序列化。在該對(duì)象的 writeobjectt()方法中,可以先調(diào)用 objectoutputstream 的 defaultwriteobject()方法, 使得對(duì)象輸出流先執(zhí)行默認(rèn)的序列化操作。同理可得出反序列化的情況,不過這次是 defaultreadobject()方法。objectoutputstrea
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 不銹鋼表面除蠟施工方案
- 2025北京東城高二(上)期末生物(教師版)
- 突發(fā)事件處置方案
- 地下室不銹鋼水池施工方案
- 紫葉矮櫻嫁接繁育技術(shù)關(guān)鍵要點(diǎn)全面深入探討與闡述
- 四川省眉山市洪雅縣洪雅縣2024-2025學(xué)年九年級(jí)上學(xué)期期末考試物理試題(原卷版+解析版)
- 室外弱電整修施工方案
- 綠色金融與可持續(xù)投資的策略
- 工業(yè)碳減排與綠色制造的策略及實(shí)施路徑
- 思維可視化視域下高中英語課堂讀后續(xù)寫教學(xué)策略研究
- 智慧農(nóng)場(chǎng)整體建設(shè)實(shí)施方案
- 被詐騙的起訴書范文
- 公路養(yǎng)護(hù)服務(wù)投標(biāo)方案(技術(shù)標(biāo))
- 灌入式半柔性復(fù)合抗車轍路面施工工法
- 小班第一學(xué)期教學(xué)進(jìn)度表
- 材料性能學(xué)課件:材料的熱學(xué)性能-2-熱傳導(dǎo)-熱穩(wěn)定性-
- 幼兒園優(yōu)質(zhì)公開課:中班數(shù)學(xué)《尋寶小勇士》課件
- 監(jiān)理單位工程項(xiàng)目總監(jiān)及監(jiān)理人員名冊(cè)
- 北師大版小學(xué)英語3-6年級(jí)單詞-(三起)帶音標(biāo)-精華版
- 聲樂第2版(學(xué)前教育專業(yè))PPT完整全套教學(xué)課件
- 《鐵道工程(A)》課程大綱
評(píng)論
0/150
提交評(píng)論