日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

詳解Java序列化機(jī)制

瀏覽:101日期:2022-08-18 18:21:00
概況

在程序中為了能直接以 Java 對象的形式進(jìn)行保存,然后再重新得到該 Java 對象,這就需要序列化能力。序列化其實(shí)可以看成是一種機(jī)制,按照一定的格式將 Java 對象的某狀態(tài)轉(zhuǎn)成介質(zhì)可接受的形式,以方便存儲或傳輸。其實(shí)想想就大致清楚基本流程,序列化時將 Java 對象相關(guān)的類信息、屬性及屬性值等等保存起來,反序列化時再根據(jù)這些信息構(gòu)建出 Java 對象。而過程可能涉及到其他對象的引用,所以這里引用的對象的相關(guān)信息也要參與序列化。Java 中進(jìn)行序列化操作需要實(shí)現(xiàn) Serializable 或 Externalizable 接口。

序列化的作用 提供一種簡單又可擴(kuò)展的對象保存恢復(fù)機(jī)制。 對于遠(yuǎn)程調(diào)用,能方便對對象進(jìn)行編碼和解碼,就像實(shí)現(xiàn)對象直接傳輸。 可以將對象持久化到介質(zhì)中,就像實(shí)現(xiàn)對象直接存儲。 允許對象自定義外部存儲的格式。 序列化例子

FileOutputStream f = new FileOutputStream('tmp.o'); ObjectOutput s = new ObjectOutputStream(f); s.writeObject('test'); s.writeObject(new ArrayList()); s.flush();

常見的使用方式是直接將對象寫入流中,比如上述例子中,創(chuàng)建了 FileOutputStream 對象,其對應(yīng)輸出到 tmp.o 文件中,然后創(chuàng)建 ObjectOutputStream 對象嵌套前面的輸出流。當(dāng)我們調(diào)用 writeObject 方法時即能進(jìn)行序列化操作。writeObject 方法這里需要說明下,在對某個對象進(jìn)行寫入時,它其實(shí)不僅僅序列化自己,還會去遍歷尋找相關(guān)引用的其他對象,由自己和其他引用對象組成的一個完整的對象圖關(guān)系都會被序列化。對于數(shù)組、enum、Class類對象、ObjectStreamClass 和 String 等都會做特殊處理,而其他對象序列化則需要實(shí)現(xiàn) Serializable 或 Externalizable 接口。

反序列化例子

FileInputStream in = new FileInputStream('tmp.o'); ObjectInputStream s = new ObjectInputStream(in); String test = (String)s.readObject(); List list = (ArrayList)s.readObject();

針對序列化則存在反序列化操作,通過流直接讀取對象,先創(chuàng)建 FileInputStream 對象,其對應(yīng)輸入文件為 tmp.o,然后創(chuàng)建 ObjectInputStream 對象嵌套前面的輸入流,接著則可以調(diào)用 readObject 方法讀取對象。其中調(diào)用 readObject 方法反序列操作的過程,除了會恢復(fù)對象自己之外還會遍歷整個完整的對象圖,創(chuàng)建整個對象圖包含的所有對象。

serialVersionUID 有什么用

在序列化操作時,經(jīng)常會看到實(shí)現(xiàn)了 Serializable 接口的類會存在一個 serialVersionUID 屬性,并且它是一個固定數(shù)值的靜態(tài)變量。比如如下,這個屬性有什么作用?其實(shí)它主要用于驗證版本一致性,每個類都擁有這么一個 ID,在序列化的時候會一起被寫入流中,那么在反序列化的時候就被拿出來跟當(dāng)前類的 serialVersionUID 值進(jìn)行比較,兩者相同則說明版本一致,可以序列化成功,而如果不同則序列化失敗。

private static final long serialVersionUID = -6849794470754667710L;

一般情況下我們可以自己定義 serialVersionUID 的值或者 IDE 幫我們自動生成,而如果我們不顯示定義 serialVersionUID 的話,這不代表不存在 serialVersionUID,而是由 JDK 幫我們生成,生成規(guī)則是會利用類名、類修飾符、接口名、字段、靜態(tài)初始化信息、構(gòu)造函數(shù)信息、方法名、方法修飾符、方法簽名等組成的信息,經(jīng)過 SHA 算法生成摘要即是最終的 serialVersionUID 值。

父類序列化什么情況

如果一個子類實(shí)現(xiàn)了 Serializable 接口而父類沒有實(shí)現(xiàn)該接口,則在序列化子類時,子類的屬性狀態(tài)會被寫入而父類的屬性狀態(tài)將不被寫入。所以如果想要父類屬性狀態(tài)也一起參與序列化,就要讓它也實(shí)現(xiàn) Serializable 接口。另外,如果父類未實(shí)現(xiàn) Serializable 接口則反序列化生成的對象會再次調(diào)用父類的構(gòu)造函數(shù),以此完成對父類的初始化。所以父類屬性初始值一般都是類型的默認(rèn)值。比如下面,F(xiàn)ather 類的屬性不會參與序列化,反序列化時 Father 對象的屬性的值為默認(rèn)值0。

public class Father {public int f; public Father() {} } public class Son extends Father implements Serializable {public int s; public Son() { super();} }哪些字段會序列化

在序列化時類的哪些字段會參與到序列化中呢?其實(shí)有兩種方式?jīng)Q定哪些字段會被序列化,1. 默認(rèn)方式,Java對象中的非靜態(tài)和非transient的字段都會被定義為需要序列的字段。2. 另外一種方式是通過 ObjectStreamField 數(shù)組來聲明類需要序列化的對象。可以看到普通的字段都是默認(rèn)會被序列化的,而對于某些包含敏感信息的字段我們不希望它參與序列化,那么最簡單的方式就是可以將該字段聲明為 transient。如何使用 ObjectStreamField?舉個例子,如下,A類中有 name 和 password 兩個字段,通過 ObjectStreamField 數(shù)組聲明只序列化 name 字段。這種聲明的方式不用糾結(jié)為什么這樣,這僅僅是約定了這樣而已。

public class A implements Serializable { String name; String passwordprivate static final ObjectStreamField[] serialPersistentFields = {new ObjectStreamField('name', String.class)}; }枚舉類型的序列化

Enum 類型的序列化與普通的 Java 類的序列化有所不同,那么在深入之前可以先看這篇文章深入了解下枚舉,《 [從JDK角度認(rèn)識枚舉enum][JDK_enum]》。所以我們知道枚舉被編譯后會變成一個繼承 java.lang.Enum 的類,而且枚舉里面的元素被聲明成 static final ,另外生成一個靜態(tài)代碼塊 static{},最后還會生成 values 和 valueOf 兩個方法。Enum 類是一個抽象類,主要有 name 和 ordinal 兩個屬性,分別用于表示枚舉元素的名稱和枚舉元素的位置索引。Enum 類型參與序列化時只會將枚舉對象中的 name 屬性寫入,而其他的屬性則不參與進(jìn)來。在反序列化時,則是先讀取 name 屬性,然后再通過 java.lang.Enum 類的 valueOf 方法找到對應(yīng)的枚舉類型。除此之外,不能自定義 Enum 類型的序列化,所以 writeObject, readObject, readObjectNoData, writeReplace 以及 readResolve 等方法在序列化時會被忽略,類似的,serialPersistentFields 和 serialVersionUID 屬性都會被忽略。最后,在序列化場景中,涉及到使用枚舉的情況時要仔細(xì)設(shè)計好,不然很可能會因為后面升級修改了枚舉類的結(jié)構(gòu)而導(dǎo)致反序列化失敗。

Externalizable 接口作用

Externalizable 接口主要就是提供給用戶自己控制序列化內(nèi)容,雖然前面我們也看到了 transient 和 ObjectStreamField 能定義序列化的字段,但通過 Externalizable 接口則能更加靈活。可以看到它其實(shí)繼承了 Serializable 接口,提供了 writeExternal 和 readExternal 兩個方法,也就是在這兩個方法內(nèi)控制序列化和反序列化的內(nèi)容。

public interface Externalizable extends java.io.Serializable { void writeExternal(ObjectOutput out) throws IOException; void readExternal(ObjectInput in) throws IOException, ClassNotFoundException; }

比如下面的例子,我們可以在 writeExternal 方法中額外寫入 Date 對象,然后再寫入 value 值。對應(yīng)的,反序列化時則是在 readExternal 方法中讀取 Date 對象和 value。這樣就完成了自定義序列化操作。

public class ExternalizableTest implements Externalizable {public String value = 'test'; public ExternalizableTest() {} public void writeExternal(ObjectOutput out) throws IOException { Date d = new Date(); out.writeObject(d); out.writeObject(value);} public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { Date d = (Date) in.readObject(); System.out.println(d); System.out.println((String) in.readObject());} }寫入時替換對象

正常情況下序列化某個對象時寫入的正是當(dāng)前的對象,但如果說我們要替換當(dāng)前的對象而寫入其他對象的話則可以通過 writeReplace 方法來實(shí)現(xiàn)。比如下面,person 類通過 writeReplace 方法最終可以寫入 Object 數(shù)組對象。所以我們在反序列化時就不再是轉(zhuǎn)換成 Person 類型,而是要轉(zhuǎn)換為 Object 數(shù)組對象。

class Person implements Serializable {private String name;private int age; public Person(String name, int age) { this.name = name; this.age = age;} private Object writeReplace() throws ObjectStreamException { Object[] properties = new Object[2]; properties[0] = name; properties[1] = age; return properties;} }

ObjectInputStream ois = new ObjectInputStream(new FileInputStream('test.o')); Object[] properties = (Object[]) ois.readObject();讀取時替換對象

上面介紹了在寫入時可以替換對象,而在讀取時也同樣支持替換對象的,它是通過 readResolve 方法實(shí)現(xiàn)的。比如下面,在 readResolve 方法返回 2222,則反序列化讀取時不再是 Person 對象,而是 2222。

class Person implements Serializable {private String name;private int age; public Person(String name, int age) { this.name = name; this.age = age;} private Object readResolve() throws ObjectStreamException { return 2222;} }

ObjectInputStream ois = new ObjectInputStream(new FileInputStream('test.o')); Object o = ois.readObject();

以上就是詳解Java序列化機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于Java序列化機(jī)制的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲精品美女91| 日韩一区精品字幕| 精品视频一区二区三区在线观看 | 亚洲欧美日本国产专区一区| 欧美偷窥清纯综合图区| 激情六月综合| 精品国产三区在线| 亚洲人成精品久久久| 亚洲午夜av| 欧美日韩免费看片| 色综合五月天| 久久精品女人| 嫩草伊人久久精品少妇av杨幂| 婷婷亚洲精品| 午夜久久久久| 国产激情一区| 国产欧美另类| 日韩和欧美的一区| 亚洲免费毛片| 亚久久调教视频| 日韩激情中文字幕| 欧美偷窥清纯综合图区| 国产精品尤物| 久久精品九色| 成人在线超碰| 四虎4545www国产精品 | 久久wwww| 精品一区二区三区的国产在线观看 | 国产日韩欧美一区在线| 日韩亚洲精品在线观看| 国产日韩欧美高清免费| 国产一区2区在线观看| 国内精品福利| 亚洲精品免费观看| 国产日产一区| 欧美日韩一二| 久久激情综合网| 久久久天天操| 日韩高清不卡一区二区| 日韩欧美精品| 日本va欧美va欧美va精品| 久久久久久色| 久久精品国产亚洲一区二区三区| 欧美精选视频一区二区| 99国产一区| 精品资源在线| 免费成人av在线播放| 精品精品国产三级a∨在线| 成人在线网站| 国产精品88久久久久久| 国产麻豆一区| 三级久久三级久久久| 日韩制服丝袜av| 99国产精品99久久久久久粉嫩| 国产精品黄网站| 亚洲色图综合| 91久久午夜| 91精品91| 亚洲二区三区不卡| 国产精品av久久久久久麻豆网| 国产精品精品| 日韩av有码| 鲁鲁在线中文| 日韩免费小视频| 国产成人精品福利| 久久只有精品| 精品国产a一区二区三区v免费| 麻豆视频一区| 成人综合一区| 日本а中文在线天堂| 国产精品欧美日韩一区| 中文字幕亚洲影视| 日韩精品视频在线看| 日韩欧美另类中文字幕| 日韩午夜在线| 久久婷婷亚洲| 亚欧洲精品视频在线观看| 成人国产精品一区二区免费麻豆| 免费成人在线影院| 国产一区国产二区国产三区| 欧美日韩国产精品一区二区亚洲| 麻豆91小视频| 日韩在线网址| 国际精品欧美精品| 国产精品久久久久毛片大屁完整版| 亚洲天堂日韩在线| 爽好久久久欧美精品| 久久不见久久见免费视频7 | 欧美日韩国产传媒| 美女视频黄免费的久久| 制服诱惑一区二区| 日本综合视频| 蜜臀av性久久久久蜜臀aⅴ流畅| 亚洲综合精品| 欧美交a欧美精品喷水| 五月激激激综合网色播| 麻豆一区二区三| 欧美在线亚洲| 久久av综合| 亚洲电影在线一区二区三区| 97久久亚洲| 福利一区二区免费视频| 亚洲乱码久久| 午夜欧美巨大性欧美巨大| 亚洲精品婷婷| 美女久久一区| 亚洲网站视频| 四虎8848精品成人免费网站| se01亚洲视频 | a日韩av网址| 婷婷精品久久久久久久久久不卡| 麻豆国产一区| 色网在线免费观看| 日本欧美大码aⅴ在线播放| 久久久久国产精品一区二区| 91大神在线观看线路一区| 成人va天堂| 亚洲综合电影| 国产一区二区三区四区| 国产日本精品| 国产欧美欧美| 久久99精品久久久久久园产越南| 国产激情欧美| 国产资源在线观看入口av| 国产农村妇女精品一二区| 国产精品片aa在线观看 | 亚洲三级毛片| 亚洲精一区二区三区| 日本欧美在线| 欧美成人亚洲| 女人天堂亚洲aⅴ在线观看| 久久狠狠久久| 亚洲97av| 国产欧美久久一区二区三区| 久久精品99久久久| 国产精品www.| 日韩精品首页| 国产精品美女久久久| 色综合视频一区二区三区日韩 | 亚洲视频www| 中文字幕系列一区| | 午夜国产欧美理论在线播放| 91精品二区| 午夜在线精品偷拍| 最新亚洲国产| 国产免费av国片精品草莓男男| 国产精品亚洲人成在99www| 午夜在线观看免费一区| 香蕉久久久久久久av网站| 日韩不卡在线观看日韩不卡视频| 日本视频在线一区| 中文在线免费视频| 综合激情五月婷婷| 精品国产鲁一鲁****| 亚洲一区中文| 成人在线视频中文字幕| 极品日韩av| 老牛影视一区二区三区| 精品资源在线| 极品日韩av| 一区二区亚洲视频| 国产精品嫩模av在线| 色欧美自拍视频| 一本一道久久a久久精品蜜桃| 四虎精品永久免费| 国产精品99一区二区三| 日韩视频久久| 国产麻豆精品| 欧美日韩在线播放视频| 日韩在线电影| 不卡专区在线| 激情欧美国产欧美| 中文字幕av一区二区三区人| 国产极品一区| 亚洲免费高清| 美女高潮久久久| 91精品亚洲| 欧美午夜三级| 久久精品高清| 91欧美极品| 999精品色在线播放| 日韩精品一页| 欧美久久天堂| 亚洲精品日本| 日韩国产欧美| 日韩av中文字幕一区| 国产成人1区| 亚洲a级精品| 波多野结衣久久精品| 日韩国产一区二| 91精品蜜臀一区二区三区在线| 欧美亚洲自偷自偷| 激情婷婷综合| 久久男人av| 蜜桃久久久久久| 日韩欧美一区二区三区免费观看| 久久久久国产精品一区三寸| 亚洲精品国产嫩草在线观看| 欧美日本三区|