程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 深刻懂得Java對象的序列化與反序列化的運用

深刻懂得Java對象的序列化與反序列化的運用

編輯:關於JAVA

深刻懂得Java對象的序列化與反序列化的運用。本站提示廣大學習愛好者:(深刻懂得Java對象的序列化與反序列化的運用)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻懂得Java對象的序列化與反序列化的運用正文


當兩個過程在停止長途通訊時,彼此可以發送各類類型的數據。不管是何品種型的數據,都邑以二進制序列的情勢在收集上傳送。發送方須要把這個Java對象轉換為字節序列,能力在收集上傳送;吸收方則須要把字節序列再恢復為Java對象。
把Java對象轉換為字節序列的進程稱為對象的序列化。
把字節序列恢復為Java對象的進程稱為對象的反序列化。
對象的序列化重要有兩種用處:
1) 把對象的字節序列永遠地保留到硬盤上,平日寄存在一個文件中;
2) 在收集上傳送對象的字節序列。
一. JDK類庫中的序列化API
java.io.ObjectOutputStream代表對象輸入流,它的writeObject(Object obj)辦法可對參數指定的obj對象停止序列化,把獲得的字節序列寫到一個目的輸入流中。
java.io.ObjectInputStream代表對象輸出流,它的readObject()辦法從一個源輸出流中讀取字節序列,再把它們反序列化為一個對象,並將其前往。
只要完成了Serializable和Externalizable接口的類的對象能力被序列化。Externalizable接口繼續自Serializable接口,完成Externalizable接口的類完整由本身來掌握序列化的行動,而僅完成Serializable接口的類可以采取默許的序列化方法 。
對象序列化包含以下步調:
1) 創立一個對象輸入流,它可以包裝一個其他類型的目的輸入流,如文件輸入流;
2) 經由過程對象輸入流的writeObject()辦法寫對象。
對象反序列化的步調以下:
1) 創立一個對象輸出流,它可以包裝一個其他類型的源輸出流,如文件輸出流;
2) 經由過程對象輸出流的readObject()辦法讀取對象。
上面讓我們來看一個對應的例子,類的內容以下:

import java.io.*;
import java.util.Date;

public class ObjectSaver {


public static void main(String[] args) throws Exception {
 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:""objectFile.obj"));

 //序列化對象
 Customer customer = new Customer("阿蜜果", 24);
 out.writeObject("你好!");
 out.writeObject(new Date());
 out.writeObject(customer);
 out.writeInt(123);
 out.close();

 //反序列化對象
 ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:""objectFile.obj"));
 System.out.println("obj1=" + (String) in.readObject());
 System.out.println("obj2=" + (Date) in.readObject());
 Customer obj3 = (Customer) in.readObject();
 System.out.println("obj3=" + obj3);
 int obj4 = in.readInt();
 System.out.println("obj4=" + obj4);
 in.close();
}
}

class Customer implements Serializable {
private String name;
private int age;
public Customer(String name, int age) {
this.name = name;
this.age = age;
}

public String toString() {
return "name=" + name + ", age=" + age;
}
}

輸入成果以下:


二.完成Serializable接口
ObjectOutputStream只能對Serializable接口的類的對象停止序列化。默許情形下,ObjectOutputStream依照默許方法序列化,這類序列化方法僅僅對對象的非transient的實例變量停止序列化,而不會序列化對象的transient的實例變量,也不會序列化靜態變量。
當ObjectOutputStream依照默許方法反序列化時,具有以下特色:
1) 假如在內存中對象所屬的類還沒有被加載,那末會先加載並初始化這個類。假如在classpath中不存在響應的類文件,那末會拋出ClassNotFoundException;
2) 在反序列化時不會挪用類的任何結構辦法。
假如用戶願望掌握類的序列化方法,可以在可序列化類中供給以下情勢的writeObject()和readObject()辦法。

private void writeObject(java.io.ObjectOutputStream out) throws IOException
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

當ObjectOutputStream對一個Customer對象停止序列化時,假如該對象具有writeObject()辦法,那末就會履行這一辦法,不然就按默許方法序列化。在該對象的writeObjectt()辦法中,可以先挪用ObjectOutputStream的defaultWriteObject()辦法,使得對象輸入流先履行默許的序列化操作。同理可得出反序列化的情形,不外此次是defaultReadObject()辦法。

有些對象中包括一些敏感信息,這些信息不宜對外地下。假如依照默許方法對它們序列化,那末它們的序列化數據在收集上傳輸時,能夠會被造孽分子盜取。關於這類信息,可以對它們停止加密後再序列化,在反序列化時則須要解密,再恢復為本來的信息。

默許的序列化方法會序列化全部對象圖,這須要遞歸遍歷對象圖。假如對象圖很龐雜,遞歸遍歷操作須要消費許多的空間和時光,它的外部數據構造為雙向列表。
在運用時,假如對某些成員變量都改成transient類型,將節儉空間和時光,進步序列化的機能。
三. 完成Externalizable接口
Externalizable接口繼續自Serializable接口,假如一個類完成了Externalizable接口,那末將完整由這個類掌握本身的序列化行動。Externalizable接口聲清楚明了兩個辦法:

public void writeExternal(ObjectOutput out) throws IOException
public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException

前者擔任序列化操作,後者擔任反序列化操作。
在對完成了Externalizable接口的類的對象停止反序列化時,會先挪用類的不帶參數的結構辦法,這是有別於默許反序列方法的。假如把類的不帶參數的結構辦法刪除,或許把該結構辦法的拜訪權限設置為private、默許或protected級別,會拋出java.io.InvalidException: no valid constructor異常。
四. 可序列化類的分歧版本的序列化兼容性
但凡完成Serializable接口的類都有一個表現序列化版本標識符的靜態變量:

private static final long serialVersionUID;

以上serialVersionUID的取值是Java運轉時情況依據類的外部細節主動生成的。假如對類的源代碼作了修正,再從新編譯,重生成的類文件的serialVersionUID的取值有能夠也會產生變更。
類的serialVersionUID的默許值完整依附於Java編譯器的完成,關於統一個類,用分歧的Java編譯器編譯,有能夠會招致分歧的serialVersionUID,也有能夠雷同。為了進步哦啊serialVersionUID的自力性和肯定性,激烈建議在一個可序列化類中顯示的界說serialVersionUID,為它付與明白的值。顯式地界說serialVersionUID有兩種用處:
1) 在某些場所,願望類的分歧版本對序列化兼容,是以須要確保類的分歧版本具有雷同的serialVersionUID;
2) 在某些場所,不願望類的分歧版本對序列化兼容,是以須要確保類的分歧版本具有分歧的serialVersionUID

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved