国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java對象序列化

2019-11-06 06:14:48
字體:
來源:轉載
供稿:網友

1.序列化與對象流

對象序列化可以將任何對象寫出到流中,并在之后將其讀回

要序列化的對象的類必須實現 Serializable接口,Serializable接口沒有任何方法

class Foo implements Serializable{...}//寫入流ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.dat"));Foo foo1 = new Foo(1);out.writeObject(foo1);//從流中讀出ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.dat"));Foo foo1 = (Foo)in.readObject();

序列化的一個重要作用是通過網絡將對象傳送到另一臺計算機,因為序列化用序列號代替內存地址,每個對象都有一個序列號

類中靜態成員不會被序列化,因為靜態成員屬于類級別,序列化只是序列化對象,所以序列化寫入的只有非瞬態非靜態數據域

讀取對象的順序與寫入時的順序要一致

2.修改默認的序列化機制

某些數據域不想或不能被序列化,用 transient (瞬態)標記,如:

PRivate transient int num;

序列化和反序列化中需要特殊處理的行為可以使用下列簽名的方法(對某些數據域)

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;private void writeObject(ObjectOutputStream out) throws IOException;//例子public class LabelPoint implements Serializable{ private String label; private transient Point2D.Double point; ... private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeDouble(point.getX()); out.writeDouble(point.getY()); } private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException { in.defaultReadObject(); double x = in.readDouble(); double y = in.readDouble(); point = new Point2D.Double(x,y); }}

readObject和writeObject方法不關心超類數據和其他類的信息。readExternal和writeExternal方法對包括超類數據在內的整個對象的存儲和恢復負責(接口不一樣)

public class Foo implements Externalizable{ private int a; private String b; private Date c; public void readExternal(ObjectInputStream in) throws IOException { a = in.readInt(); b = in.readString(); c = new Date(in.readLong()); } public void writeExternal(ObjectOutputStream out) throws IOException { out.writeInt(a); out.writeString(b); out.writeLong(c.getTime()); }}

3.序列化單例和類型安全的枚舉

類型安全的枚舉和單例模式的類需要添加readResolve方法,因為此時默認的序列化機制不起作用。

readResolve方法在對象被序列化之后被調用,必須返回一個對象,此對象會成為之后readObject方法的返回值,如:

class Foo implements Serializable{ public static final Foo TEST1=new Foo(1); public static final Foo TEST2=new Foo(2); private int value; private Foo(int v){value=v;}}//TEST1是單例Foo original = Foo.TEST1;ObjectOutputStream out = ...out.writeObject(foo1);out.close();//此時saved和original不是同一個對象,errorObjectInputStream in = ...Foo saved = (Foo)in.readObject();//Foo類中添加readResolveprotected Object readResolve() throws ObjectStreamException{ if(value==1) return Foo.TEST1; if(value==2) return Foo.TEST2; return null; //這一步不應該發生}

4.版本管理

類可以對其早期版本進行兼容,但必須有這個類早期版本的指紋,即 serialVersionUID,此靜態數據成員被放在某個類,則序列化系統就可以讀入這個類的對象的不同版本(這個類的所有較新版本都必須把 serialVersionUID 定義為與初始版本相同)

class Foo implements Serializable{ ... public static final long serialVersionUID=-133423423L;}

如果這個類只有方法發生了變化,則讀入新對象數據時不會有問題;如果數據域發生了變化,則可能有問題,對象流將盡力將流對象轉換成這個類的當前版本,做法如下(不處理瞬態和靜態數據域):

對于數據域名字匹配,類型不匹配,不會轉換流中對象具有當前版本沒有的數據域,則忽略這些數據域當前版本具有流對象中沒有的數據域,則這些新添加的數據域設置成他們的默認值,對象為null,數字為0,boolean為false

參考文獻:java核心技術卷2


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 嘉兴市| 凤翔县| 滨海县| 日照市| 尚义县| 铜梁县| 崇州市| 石首市| 卓资县| 谢通门县| 西峡县| 江西省| 綦江县| 花莲县| 吕梁市| 南川市| 天镇县| 滕州市| 蚌埠市| 北票市| 女性| 疏附县| 华亭县| 玉树县| 鄂尔多斯市| 桦南县| 宁蒗| 咸丰县| 西城区| 安图县| 安阳县| 台北市| 浮山县| 西吉县| 蒙自县| 云阳县| 云林县| 九台市| 恩施市| 贺兰县| 依兰县|