Java基礎(28)——對象的序列化詳解及示例分析
版權聲明
- 本文原創作者:清風不渡
- 博客地址:https://blog.csdn.net/WXKKang
一、對象的序列化
(1)什麼是對象序列化
前兩篇我們學習了字節流與字符流,通過它們我們既可以把數據從硬盤中讀取出來,也可以把數據儲存在硬盤中,那麼我們是否可以將我們在程序中創建的對象也存儲在硬盤中呢?當然是可以的
當創建對象時,程序運行時它就會存在,但是程序停止時,對象也就消失了。但是如果希望永久保存這些對象,則可以將對象轉爲字節數據寫入到硬盤上並保存其信息,當對象將被重建時它並且擁有與程序上次運行時擁有的信息相同,這就是對象的序列化。
基本的序列化由兩個方法產生:一個方法用於序列化對象並將它們寫入一個流,另一個方法用於讀取流並反序列化對象,如下:
(2)API
ObjectOutputStream和ObjectInputStream 對象分別需要字節輸出流和字節輸入流對象來構建對象,因此,這兩個流對象可以將對象進行本地持久化存儲
(3)Serializable接口
實現javaio.Serializable接口的類將啓用其序列化功能,未實現此接口的類將無法使其任何狀態序列化或反序列化。所以需要被序列化的類必須是實現Serializable接口,該接口中沒有描述任何的屬性和方法,稱之爲標記接口。如果對象沒有實現接口Serializable, 在進行序列化時會拋出NotSerializableException異常
serialVersionUID用於給類指定一個UID。如果被序列化的對象需要被不同的類版本所兼容,可以在類中自定義serialVersionUID。定義方式:static final long serialVersionUID = 42L;
(4)案例:序列化和反序列化Dog對象
代碼及註釋如下:
package qfbd.com;
/*
原創作者:清風不渡
博客地址:https://blog.csdn.net/WXKKang
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Demo {
public static void main(String[] args) throws Exception {
//創建dog對象
Dog dog = new Dog("貝貝", 2);
//序列化
FileOutputStream fileOutputStream = new FileOutputStream("D:"+File.separatorChar+"dog.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(dog);
System.out.println("寫入文件的對象:"+dog);
objectOutputStream.flush();
objectOutputStream.close();
//反序列化
FileInputStream fileInputStream = new FileInputStream("D:"+File.separatorChar+"dog.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Object readObject = objectInputStream.readObject();
Dog dog2 = (Dog)readObject;
System.out.println("從文件中讀出的對象:"+dog2);
objectInputStream.close();
}
}
//實現Serializable接口並生成序列號
class Dog implements Serializable{
private static final long serialVersionUID = 6634752521947304823L;
public String name;
public int age;
public Dog() {
// TODO Auto-generated constructor stub
}
//添加帶參構造函數
public Dog(String name,int age){
this.name = name;
this.age = age;
}
//重寫toString方法
@Override
public String toString() {
return "Dog[name="+name+",age="+age+"]";
}
}
執行結果如下:
由上面的示例我們可以看出,我們將dog對象儲存入了硬盤中,最後又讀了出來,實現了對象的存儲與讀取
關鍵點:
(1)聲明Cat類實現了Serializable 接口,是一個標示器,沒有要實現的方法
(2)新建Cat對象,對象中不想序列化的對象使用transient關鍵字修飾
(3)新建字節流對象(FileOutputStream)進序列化對象保存在本地文件中
(4)新建ObjectOutputStream對象,調用writeObject方法序列化Cat對象
(5) writeObject方法會執行兩個工作:序列化對象,然後將序列化的對象寫入文件中
(6)反序列化就是調用ObjectInputStream的readObject()方法
(7)異常處理和流的關閉動作要執行
(8)注意:序列化是遞歸的,如果對象中包含其它可序列化的對象,其它對象也會被序列化