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

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

JAVA序列化Serializable及Externalizable區(qū)別詳解

瀏覽:37日期:2022-08-29 10:08:21

序列化簡(jiǎn)介

Java 的對(duì)象序列化將那些實(shí)現(xiàn) Serializable 接口的對(duì)象轉(zhuǎn)換成一個(gè)字節(jié)序列,并能在之后將這個(gè)字節(jié)序列完全恢復(fù)為原來的對(duì)象。這就意味著 Java 對(duì)象在網(wǎng)絡(luò)上的傳輸可以不依賴于當(dāng)前計(jì)算機(jī)的操作系統(tǒng),就可以將對(duì)象進(jìn)行傳遞,這也是Java跨平臺(tái)的一種體現(xiàn)。

Java 對(duì)象的序列化主要支持兩種特性:

1、Java的遠(yuǎn)程方法調(diào)用(Remote Method Invocation RMI);

2、對(duì)于 JavaBean 來說,序列化也是必須的。

要序列化一個(gè)對(duì)象,需要?jiǎng)?chuàng)建一個(gè) OutputStream 對(duì)象,然后將其封裝在 ObjectOutputStream 對(duì)象中,再調(diào)用 writeObject() 方法就可以完成對(duì)象的序列化(也是在這一步進(jìn)行序列化);反序列化(將一個(gè)序列還原為一個(gè)對(duì)象)就是該過程的反過程:創(chuàng)建一個(gè) InputStream 對(duì)象,將其封裝在 ObjectInputStream 對(duì)象中,使用 readObject() 方法將序列反序列化為對(duì)象,當(dāng)然這是一個(gè)Object類型的對(duì)象,需要向下轉(zhuǎn)型為我們需要的類型(如果該類型不在本地,會(huì)導(dǎo)致反序列化失敗,ClassNotFoundException )。

先說結(jié)論

序列化有以下方式:

1、實(shí)現(xiàn) Serializable 接口:

2、實(shí)現(xiàn) Externalizable 接口,并重寫 writeExternal() readExternal() 方法;

3、(即下文中的 Externalizable 的替代方式進(jìn)行序列化)如果不想實(shí)現(xiàn)Externalizable 接口,又想按照自己的規(guī)則進(jìn)行序列化,可以實(shí)現(xiàn) Serializable 接口,并在該類中添加(添加,不是覆蓋、實(shí)現(xiàn))名為 writeExternal() readExternal() 方法,且這兩個(gè)方法必須為下面這兩個(gè)準(zhǔn)確的方法簽名:

private void writeObject(ObjectOutputStream stream) throws IOException;private void readObject(ObjectInputStream stream) throws IOException,ClassNotFoundException;

一、三種方式完成序列化

1、實(shí)現(xiàn) Serializable 接口序列化

這種方式最為常用且常見,只需要對(duì)需要序列化的類實(shí)現(xiàn) Serializable 即可,對(duì)于不希望進(jìn)行序列化的,可以使用 transient 關(guān)鍵詞進(jìn)行修飾(即瞬時(shí)變量)。這種方式序列化的特征:

1、 Serializable 接口僅僅是一個(gè)標(biāo)記接口,不包含任何方法;

2、對(duì)于Serializable對(duì)象來說,對(duì)象完全以它存儲(chǔ)的二進(jìn)制位為基礎(chǔ)來構(gòu)造,(反序列化)不會(huì)調(diào)用構(gòu)造器。

2、實(shí)現(xiàn) Externalizable 接口序列化

這種方式可以實(shí)現(xiàn)序列化的完全自定義:所有成員變量是否序列化都需要在 writeExternal()、readExternal()方法中寫出;且可以完全自定義序列化方式(在 writerExternal()、readExternal()方法中)。當(dāng)然,實(shí)現(xiàn) Externalizable 接口必須要重寫這兩個(gè)方法。這種方式序列化的特征:

1、必須重寫 writerExternal()、readExternal()兩個(gè)方法,并在兩個(gè)方法中寫出所有需要序列化的成員變量;

2、對(duì)于 Externalizable對(duì)象來說,必須要有無參public構(gòu)造器,不然會(huì)報(bào)出 InvalidClassException 異常。

3、 Externalizable 的替代方式進(jìn)行序列化

讓 ObjectOutputStream 和 ObjectInputStream 對(duì)象的 writeObject() 方法和 readObject() 方法調(diào)用我們編寫的這兩個(gè)方法。如果想在這種方式中也調(diào)用原有默認(rèn)提供的方式,可以在 writeObject() 中調(diào)用: s.defaultWriteObject();,在 readObject() 中調(diào)用 s.defaultReadObject();。 這部分代碼可以查看 ArrayList 源碼。

二、測(cè)試代碼

1、 Serializable 對(duì)象反序列化,不調(diào)用任何構(gòu)造器

Serializable 對(duì)象反序列化不調(diào)用任何構(gòu)造器,包括默認(rèn)構(gòu)造器,整個(gè)對(duì)象都是從 InputStream 中取得數(shù)據(jù)恢復(fù)過來的

主測(cè)試類 Dogs

public class Dogs { public static void main(String[] args) throws Exception { // 創(chuàng)建對(duì)象 System.out.println('--- 創(chuàng)建對(duì)象 ---'); Dog1 d1 = new Dog1('pidan',4.0); Dog2 d2 = new Dog2('duanwu','black'); // 序列化 System.out.println('--- 序列化 ---'); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream('D:/dogs.out')); oos.writeObject(d1); oos.writeObject(d2); System.out.println('--- 反序列化 ---'); // 反序列化 不會(huì)調(diào)用任何構(gòu)造器 ObjectInputStream ois = new ObjectInputStream(new FileInputStream('d:/dogs.out')); Dog1 o1 = (Dog1) ois.readObject(); Dog2 o2 = (Dog2) ois.readObject(); System.out.println('反序列化 o1 : ' + o1); System.out.println('反序列化 o2 : ' + o2); }}

Serializable 對(duì)象 Dog1 Dog2 類

class Dog1 implements Serializable { private static final long serialVersionUID = -7101743601344663182L; private String name; private Double weight; public Dog1(String name, Double weight) { System.out.println('Dog1 構(gòu)造器運(yùn)行 ---'); this.name = name; this.weight = weight; System.out.println('Dog1 : ' + this); } // 省略get、set、toString方法}public class Dog2 implements Serializable { private static final long serialVersionUID = -5462607652670703938L; private String name; private String color; public Dog2(String name, String color) { System.out.println('Dog2 構(gòu)造器運(yùn)行 ---'); this.name = name; this.color = color; System.out.println('Dogs2 : ' + this); } // 省略get、set、toString方法}

運(yùn)行結(jié)果:

--- 創(chuàng)建對(duì)象 ---Dog1 構(gòu)造器運(yùn)行 ---Dog1 : Dog1{name=’pidan’, weight=4.0}Dog2 構(gòu)造器運(yùn)行 ---Dogs2 : Dog2{name=’duanwu’, color=’black’}--- 序列化 ------ 反序列化 ---反序列化 o1 : Dog1{name=’pidan’, weight=4.0}反序列化 o2 : Dog2{name=’duanwu’, color=’black’}

再最后取出對(duì)象時(shí),完全沒有調(diào)用到其任何構(gòu)造器。

2、無參構(gòu)造器對(duì) Externalizable 對(duì)象序列化的影響

主測(cè)試代碼:

public class Persons { public static void main(String[] args) throws Exception { // 創(chuàng)建對(duì)象 System.out.println('Init Objects'); Person1 p1 = new Person1(); Person2 p2 = new Person2(); // 存儲(chǔ)在磁盤上 ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream('d:/person.out')); os.writeObject(p1); os.writeObject(p2); os.flush(); os.close(); // 取出 ObjectInputStream is = new ObjectInputStream(new FileInputStream('d:/person.out')); System.out.println('取出p1: '); p1 = (Person1) is.readObject(); p2 = (Person2) is.readObject(); }}

Externalizable 對(duì)象:Perion1 Persion2

public class Person1 implements Externalizable { public Person1(){ System.out.println('Person1 構(gòu)造器---'); } @Override public void writeExternal(ObjectOutput out) throws IOException { System.out.println('Person1 writeExternal ---'); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println('Person1 readExternal ---'); }}class Person2 implements Externalizable{ // 注意不是public Person2(){ System.out.println('Person2 構(gòu)造器 ---'); } @Override public void writeExternal(ObjectOutput out) throws IOException { System.out.println('Person2 writeExternal ---'); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println('Person2 readExternal ---'); }}

Person2 默認(rèn)構(gòu)造器不是 public 的運(yùn)行結(jié)果:

Init ObjectsPerson1 構(gòu)造器---Person2 構(gòu)造器 ---Person1 writeExternal ---Person2 writeExternal ---取出p1: Person1 構(gòu)造器---Person1 readExternal ---Exception in thread 'main' java.io.InvalidClassException: ...serializableAndexternalizable.Person2; no valid constructorat java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:169)at java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:874)at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2043)at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)at ...serializableAndexternalizable.Persons.main(Persons.java:29)Process finished with exit code 1

將 Person2 構(gòu)造器改為 public 后:

Init ObjectsPerson1 構(gòu)造器---Person2 構(gòu)造器 ---Person1 writeExternal ---Person2 writeExternal ---取出p1: Person1 構(gòu)造器---Person1 readExternal ---Person2 構(gòu)造器 ---Person2 readExternal ---

3、使用 Externalizable 對(duì)象實(shí)現(xiàn)序列化

主測(cè)試類 Cats :

public class Cats { public static void main(String[] args) throws Exception { // 初始化對(duì)象 System.out.println('--- 初始化對(duì)象 ---'); Person person = new Person('01', '老王', 30); Cat2 cat = new Cat2('fugui', person); // 序列化 System.out.println('--- 序列化對(duì)象 ---'); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream('d:/cats.out')); oos.writeObject(cat); System.out.println('--- 反序列化對(duì)象 ---'); ObjectInputStream ois = new ObjectInputStream(new FileInputStream('d:/cats.out')); cat = (Cat2) ois.readObject(); System.out.println('--- 反序列化對(duì)象后 ---'); System.out.println('cat : ' + cat); }}

Externalizable 對(duì)象: Cat2 ;Serializable 對(duì)象:Person :

public class Person implements Serializable { private static final long serialVersionUID = -822166081906894628L; private transient String id; private String name; private int age; public Person() { System.out.println('--- Person 無參構(gòu)造器 ---'); } public Person(String id, String name, int age) { System.out.println('--- Person 無參構(gòu)造器 ---'); this.id = id; this.name = name; this.age = age; System.out.println('Person : ' + this); } // 省略get、set、toString方法}class Cat2 implements Externalizable { private static final long serialVersionUID = 1102930161606017855L; private String name; private Person minion; public Cat2() { System.out.println('Cat2 無參構(gòu)造器 --->'); } public Cat2(String name, Person minion) { System.out.println('Cat2 有參構(gòu)造器 --->'); this.name = name; this.minion = minion; System.out.println('Cat2 : ' + this); } // 省略get、set、toString方法 @Override public void writeExternal(ObjectOutput out) throws IOException { System.out.println('--- Cat2:writeExternal ---'); // code1 out.writeObject(this.minion); out.writeObject(this.name); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println('--- Cat2:readExternal ---'); // code2 this.minion = (Person) in.readObject(); this.name = (String) in.readObject(); }}

運(yùn)行結(jié)果:

可以注意到Person的成員變量id在使用了 transient 關(guān)鍵詞修飾后,就不再序列化該字段了。

--- 初始化對(duì)象 ------ Person 無參構(gòu)造器 ---Person : Person{id=’01’, name=’老王’, age=30}Cat2 有參構(gòu)造器 --->Cat2 : Cat2{name=’fugui’, minion=Person{id=’01’, name=’老王’, age=30}}--- 序列化對(duì)象 ------ Cat2:writeExternal ------ 反序列化對(duì)象 ---Cat2 無參構(gòu)造器 --->--- Cat2:readExternal ------ 反序列化對(duì)象后 ---cat : Cat2{name=’fugui’, minion=Person{id=’null’, name=’老王’, age=30}}

如果將Cat2類中標(biāo)注的 code1 與 code2 代碼下面的兩行代碼均注釋掉,就不再可以序列化及反序列化了:注釋掉后的運(yùn)行結(jié)果:

--- 初始化對(duì)象 ------ Person 無參構(gòu)造器 ---Person : Person{id=’01’, name=’老王’, age=30}Cat2 有參構(gòu)造器 --->Cat2 : Cat2{name=’fugui’, minion=Person{id=’01’, name=’老王’, age=30}}--- 序列化對(duì)象 ------ Cat2:writeExternal ------ 反序列化對(duì)象 ---Cat2 無參構(gòu)造器 --->--- Cat2:readExternal ------ 反序列化對(duì)象后 ---cat : Cat2{name=’null’, minion=null}

4、使用 Externalizable 對(duì)象替代方式實(shí)現(xiàn)序列化

替代方式就是實(shí)現(xiàn) Serializable 接口,并且添加 writeObject(),readObject() 兩個(gè)方法注意這兩個(gè)方法必須有準(zhǔn)確的方法特征簽名,在這兩個(gè)方法中編寫自定義方式實(shí)現(xiàn)序列化和反序列化。

class Mouse implements Serializable { private static final long serialVersionUID = -3278535893876444138L; private String name; private int i; public Mouse() { System.out.println('Mouse 無參構(gòu)造器 ---'); } public Mouse(String name, int i) { System.out.println('Mouse 有參構(gòu)造器 ---'); this.name = name; this.i = i; System.out.println('Mouse : ' + this); } // 方法特征簽名必須完全一致 private void writeObject(ObjectOutputStream stream) throws IOException {// stream.defaultWriteObject();// 可以選擇執(zhí)行默認(rèn)的writeObject() System.out.println('--- 這是自定義的writeExternal方法 ---'); stream.writeObject(this.name); stream.writeInt(this.i); } // 方法特征簽名必須完全一致 private void readObject(ObjectInputStream stream) throws IOException,ClassNotFoundException {// stream.defaultReadObject(); // 可以選擇執(zhí)行默認(rèn)的readObject() System.out.println('--- 這是自定義的readExternal方法 ---'); this.name = (String)stream.readObject(); this.i = stream.readInt(); } // 省略get、set、toString方法}

主測(cè)試類:

public class Mouses { public static void main(String[] args) throws Exception { // 創(chuàng)建對(duì)象 System.out.println('--- 創(chuàng)建對(duì)象 ---'); Mouse m1 = new Mouse('zhizhi', 2); // 序列化 System.out.println('--- 序列化 ---'); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream('D:/mouse.out')); oos.writeObject(m1); // 反序列化 System.out.println('--- 反序列化 ---'); ObjectInputStream ois = new ObjectInputStream(new FileInputStream('d:/mouse.out')); // 反序列化結(jié)果 System.out.println('--- 反序列化結(jié)果 ---'); m1 = (Mouse) ois.readObject(); System.out.println(' zhizhi : ' + m1); }}

運(yùn)行結(jié)果

--- 創(chuàng)建對(duì)象 ---Mouse 有參構(gòu)造器 ---Mouse : Mouse{name=’zhizhi’, i=2}--- 序列化 ------ 這是自定義的writeExternal方法 ------ 反序列化 ------ 反序列化結(jié)果 ------ 這是自定義的readExternal方法 ---zhizhi : Mouse{name=’zhizhi’, i=2}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲精品日韩久久| 久久国内精品视频| 成人台湾亚洲精品一区二区| 亚洲国产日韩欧美在线| 久久久天天操| 日韩精品永久网址| 神马久久午夜| 色爱综合av| 国产综合精品| 蜜臀久久99精品久久一区二区| 麻豆久久一区| 日本午夜大片a在线观看| 国产欧美欧美| 欧美偷窥清纯综合图区| 中文字幕日韩高清在线| 蘑菇福利视频一区播放| 国产图片一区| 欧美精品影院| 亚洲欧美日本视频在线观看| 精品一区毛片| 亚洲我射av| 日韩av电影一区| 国产精品一区高清| 精品国产aⅴ| 欧美sss在线视频| 国产手机视频一区二区| 青草国产精品| 国产一区二区三区精品在线观看| 国产麻豆久久| 亚洲一区二区动漫| 97久久亚洲| 国产成人77亚洲精品www| 韩国三级一区| 不卡在线一区二区| 日韩三级精品| 精品网站999| 久久久久一区| 中文字幕中文字幕精品| 欧美91在线| 五月天综合网站| 日韩精品免费观看视频| 精品一级视频| 午夜日本精品| 人人爱人人干婷婷丁香亚洲| 水蜜桃精品av一区二区| 亚洲欧洲日本mm| 国产精品a级| 激情五月综合| 日韩三级精品| 久久蜜桃精品| 国产欧美一区二区三区精品观看 | 久久精品一区二区不卡| | 麻豆国产欧美日韩综合精品二区| 久久国产成人| 成人自拍av| 国语精品一区| 精品国产欧美| 日韩一二三区在线观看| 中文字幕一区日韩精品| 国产亚洲永久域名| 国精品一区二区三区| 日韩精品1区2区3区| 成人污污视频| 蜜臀av亚洲一区中文字幕| 麻豆网站免费在线观看| 色狠狠一区二区三区| 天堂av在线| 国产亚洲电影| 日韩午夜免费| 日韩一区三区| 国产欧美日韩免费观看| 国产精品91一区二区三区| 一区二区国产精品| 久久国产免费| 久久永久免费| 日韩高清在线不卡| 亚洲免费观看| 91tv亚洲精品香蕉国产一区| 国产精东传媒成人av电影| 视频一区视频二区中文字幕| 中文字幕在线高清| 国产日本久久| 只有精品亚洲| 女人av一区| 欧美羞羞视频| 美日韩一区二区三区| 亚洲三级毛片| 婷婷激情综合| 亚洲欧洲高清| 精品视频网站| 国产亚洲精品美女久久久久久久久久| 老色鬼久久亚洲一区二区| 日韩免费一区| 久久精品国产99国产精品| 日本在线视频一区二区| 欧美专区18| 亚洲二区视频| 肉色欧美久久久久久久免费看| 免费日韩成人| 国产精品xxxav免费视频| 亚洲久草在线| 伊人精品久久| 欧洲毛片在线视频免费观看| 日韩大片免费观看| av最新在线| 国产一区二区三区黄网站| 国产精品videossex久久发布| 日韩欧美久久| 亚洲资源在线| 亚洲一区av| 亚洲青青久久| 日韩精品第一| 欧美亚洲三级| 国产免费av国片精品草莓男男| 日韩三级久久| 日韩二区在线观看| 日本成人一区二区| 亚洲天堂av资源在线观看| 一区二区视频欧美| 怡红院精品视频在线观看极品| 欧美13videosex性极品| 在线亚洲人成| 日韩精品看片| 欧美在线观看视频一区| 欧美成人日韩| 午夜精品婷婷| 水蜜桃久久夜色精品一区的特点| 亚洲欧美日韩国产| 中文字幕成人| 日韩av中文在线观看| 日本欧美韩国一区三区| 日本欧美大码aⅴ在线播放| 四虎精品永久免费| 日本亚洲最大的色成网站www| 日本麻豆一区二区三区视频| 国产欧美日韩免费观看| 精品三级国产| 日本免费久久| 美女毛片一区二区三区四区| 精品1区2区3区4区| 每日更新成人在线视频| 日本不卡视频在线| 国产精品一国产精品| 成人午夜亚洲| 欧美中文字幕一区二区| 久久福利精品| 国产精品一级| 国产精品久久观看| 久久亚洲国产| 亚洲一区二区小说| 欧美极品一区二区三区| 亚洲一级少妇| 巨乳诱惑日韩免费av| 国产日产精品一区二区三区四区的观看方式| 国产精品一二| 日韩一区亚洲二区| 久久一二三区| 国产调教精品| 亚洲精品在线影院| 丝袜诱惑制服诱惑色一区在线观看| 日韩中文一区二区| 精品国产亚洲一区二区三区| 亚洲va中文在线播放免费| 夜久久久久久| 91精品国产自产观看在线| 欧美xxxx中国| 亚洲一级在线| 乱一区二区av| 国产婷婷精品| 精品黄色一级片| 黄色成人在线网址| 97成人在线| 日韩一区三区| 在线精品国产亚洲| 久久99国产精品视频| 成人av二区| 国产精品黄色| 亚洲手机在线| 国产欧美欧美| 狠狠色狠狠色综合日日tαg| 国产精品99久久免费| 欧美成人亚洲| 国产精品久久久亚洲一区| 美女少妇全过程你懂的久久| 欧美日韩1区| 免费黄色成人| 麻豆精品视频在线| 亚洲自拍另类| 国产一区二区三区国产精品| 三级欧美在线一区| 国产一区二区三区天码| 巨乳诱惑日韩免费av| 精品久久一区| 中文字幕成人| 国产综合精品一区| 毛片不卡一区二区| 亚洲精品女人| 午夜免费一区| av最新在线|