日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JAVA 对象序列化(二)——Externalizable

發布時間:2025/5/22 编程问答 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA 对象序列化(二)——Externalizable 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java默認的序列化機制非常簡單,而且序列化后的對象不需要再次調用構造器重新生成,但是在實際中,我們可以會希望對象的某一部分不需要被序列化,或者說一個對象被還原之后,其內部的某些子對象需要重新創建,從而不必將該子對象序列化。 在這些情況下,我們可以考慮實現Externalizable接口從而代替Serializable接口來對序列化過程進行控制(后面我們會講到一個更簡單的方式,通過transient的方式)。

? ? ?Externalizable接口extends?Serializable接口,而且在其基礎上增加了兩個方法:writeExternal()和readExternal()。這兩個方法會在序列化和反序列化還原的過程中被自動調用,以便執行一些特殊的操作。

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

? ? ?下面這段代碼示范了如何完整的保存和恢復一個Externalizable對象

package test.serializable;import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput;public class Blip implements Externalizable {private int i ;private String s;//沒有初始化public Blip() {//默認構造函數必須有,而且必須是publicSystem.out.println("Blip默認構造函數");}public Blip(String s ,int i) {//s,i只是在帶參數的構造函數中進行初始化。System.out.println("Blip帶參數構造函數");this.s = s;this.i = i;}public String toString() {return s + i ;}@Overridepublic void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {System.out.println("調用readExternal()方法");s = (String)in.readObject();//在反序列化時,需要初始化s和i,否則只是調用默認構造函數,得不到s和i的值i = in.readInt();}@Overridepublic void writeExternal(ObjectOutput out) throws IOException {System.out.println("調用writeExternal()方法");out.writeObject(s); //如果我們不將s和i的值寫入的話,那么在反序列化的時候,就不會得到這些值。out.writeInt(i);}} package test.serializable;import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream;public class ExternalizableTest {/*** @param args* @throws IOException * @throws ClassNotFoundException */public static void main(String[] args) throws IOException, ClassNotFoundException {System.out.println("序列化之前");Blip b = new Blip("This String is " , 47);System.out.println(b);System.out.println("序列化操作,writeObject");ByteArrayOutputStream out = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(out);oos.writeObject(b);System.out.println("反序列化之后,readObject");ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());ObjectInputStream ois = new ObjectInputStream(in);Blip bb = (Blip)ois.readObject();System.out.println(bb); } }

運行結果如下所示:? ? ?

序列化之前 Blip帶參數構造函數 This String is 47 序列化操作,writeObject 調用writeExternal()方法 反序列化之后,readObject Blip默認構造函數 調用readExternal()方法 This String is 47

分析結果:

? ? ?在Blip類中,字段s和i只在第二個構造器中初始化,而不是在默認的構造器其中初始化的,每次writeObject時,都會調用WriteExtenal()方法,而在WriteExtenal()方法中我們需要將當前對象的值寫入到流中;而每次readObject()時,調用的是默認的構造函數,如果我們不在 readExternal()方法中初始化s和i,那么s就會為null,而i就會為0。

下面分幾種情況討論:

??1) 如果我們只修改writeExternal()方法如下:

@Overridepublic void writeExternal(ObjectOutput out) throws IOException {System.out.println("調用writeExternal()方法"); // out.writeObject(s); // out.writeInt(i);}

那么運行的結果為:

序列化之前 Blip帶參數構造函數 This String is 47 序列化操作,writeObject 調用writeExternal()方法 反序列化之后,readObject Blip默認構造函數 調用readExternal()方法 Exception in thread "main" java.io.OptionalDataExceptionat java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1349)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)at test.serializable.Blip.readExternal(Blip.java:34)at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)at test.serializable.ExternalizableTest.main(ExternalizableTest.java:28)

? ? ? 原因是因為,我們在ObjectOutPutStream中沒有writeObject,而在ObjectInputStream中readObject導致的

?2)如果我們修改writeExternal()方法如下:

@Overridepublic void writeExternal(ObjectOutput out) throws IOException {System.out.println("調用writeExternal()方法");out.writeObject("自己定義的");out.writeInt(250);}

那么運行的結果為:

序列化之前 Blip帶參數構造函數 This String is 47 序列化操作,writeObject 調用writeExternal()方法 反序列化之后,readObject Blip默認構造函數 調用readExternal()方法 自己定義的250

看見沒,反序列化后得到的s和i是我們在writeExternal()中自定義的數據

? 3) 如果我們只是修改readExternal()方法

@Overridepublic void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {System.out.println("調用readExternal()方法"); // s = (String)in.readObject(); // i = in.readInt();}

那么運行的結果為:

序列化之前 Blip帶參數構造函數 This String is 47 序列化操作,writeObject 調用writeExternal()方法 反序列化之后,readObject Blip默認構造函數 調用readExternal()方法 null0

? ?看見沒?最后一行打印的是null0,說明沒有對s和i進行初始化。

4)如果我們刪除Blip的默認構造函數,或者將其權限不設置為public

// public Blip() { // //默認構造函數必須有,而且必須是public // System.out.println("Blip默認構造函數"); // } // orBlip() {//默認構造函數必須有,而且必須是publicSystem.out.println("Blip默認構造函數");}

運行結果如下:

序列化之前 Blip帶參數構造函數 This String is 47 序列化操作,writeObject 調用writeExternal()方法 反序列化之后,readObject Exception in thread "main" java.io.InvalidClassException: test.serializable.Blip; test.serializable.Blip; no valid constructorat java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:713)at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1733)at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)at test.serializable.ExternalizableTest.main(ExternalizableTest.java:28) Caused by: java.io.InvalidClassException: test.serializable.Blip; no valid constructorat java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:471)at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:310)at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1106)at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)at test.serializable.ExternalizableTest.main(ExternalizableTest.java:24)

? 在反序列化時,會出現無效的構造函數這個錯誤,可見必須有權限為public的默認的構造器(如果有非默認的帶參數的構造函數,那么必須顯示的寫出默認的構造函數,如果沒有非默認的構造函數,那么默認構造函數可以不顯示的寫出來),才能使Externalizable對象產生正確的行為。

總結Externalizable對象的用法:

? ? 與Serizable對象不同,使用Externalizabled,就意味著沒有任何東西可以自動序列化,?為了正常的運行,我們需要在writeExtenal()方法中將自對象的重要信息寫入,從而手動的完成序列化。對于一個Externalizabled對象,對象的默認構造函數都會被調用(包括哪些在定義時已經初始化的字段),然后調用readExternal(),在此方法中必須手動的恢復數據。

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的JAVA 对象序列化(二)——Externalizable的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人小视频免费在线观看 | 91九色丨porny丨国产jk | 综合视频| 亚洲成人诱惑 | 日本特级片| 婷婷色在线视频 | 高h喷水荡肉少妇爽多p视频 | 亚洲一区二区三区免费视频 | 夜夜操夜夜爱 | 成年人激情网站 | 国产一区日本 | 91精品国产99久久久久久红楼 | 免费观看毛片 | 欧美性生活一区二区三区 | 欧美国产日韩一区 | 欧美三级欧美一级 | 国产视频精品自拍 | 黄色大片a级 | 在线观看视频一区二区三区 | 久久久久无码精品国产sm果冻 | 一区二区精品视频 | 亚洲精品福利网站 | 黄色香蕉网站 | 一区二区伦理片 | 性色av一区二区三区红粉影视 | 成人免费毛片嘿嘿连载视频 | 波多野吉衣一二三区乱码 | 蜜桃av在线看 | 边啃奶头边躁狠狠躁 | 亚洲欧美变态另类丝袜第一区 | 国产精品嫩草影院精东 | av大片免费看 | 亚洲三区在线 | 欧美成人h | 在线天堂v | 韩国三级视频在线 | 欧美日韩卡一卡二 | 卡一卡二在线视频 | 五月视频 | 成年人视频在线观看免费 | cao死你| 久久毛片基地 | 韩日av在线| 97成人人妻一区二区三区 | 蜜桃免费在线视频 | 波多野结衣电影免费观看 | 亚洲欧洲天堂 | 亚洲国产果冻传媒av在线观看 | 四虎av网站| h视频在线看| av网站免费在线观看 | 黄色录像二级片 | 又黄又爽的网站 | 色校园 | 久久性生活视频 | 亚洲综合久久网 | 在线国产黄色 | 成人国产在线观看 | 另类男人与善交video | 成人av网址在线观看 | 国产免费一级视频 | 欧美性猛片aaaaaaa做受 | 午夜免费福利小视频 | 精品欧美一区二区三区久久久 | 久久国产精品久久久久久 | 成人亚洲黄色 | 96视频在线观看 | 99色精品 | 告诉我真相俄剧在线观看 | 美女黄色在线观看 | 国产免费视频 | 午夜整容室 | 日本久久中文字幕 | 欧美成人第一页 | 黄色免费在线播放 | 日本在线看片 | 亚洲中出| 婷婷激情五月网 | 欧美福利一区 | 变态另类一区二区 | 中文字幕精品一区二区三区精品 | 88xx成人永久免费观看 | 成人国产在线观看 | 中文在线免费 | 一本高清视频 | 亚洲黄页网站 | 亚洲精品第一 | 91最新地址永久入口 | 777色婷婷 | 国产精品一卡 | www.777含羞草 | 在线免费观看黄网站 | 岛国精品 | 黄网视频在线观看 | 日日夜夜影院 | 欧美日韩1区 | 春色校园激情 | 久久一区二区三区四区 | 日本护士╳╳╳hd少妇 |