把對象轉換為位元組序列的過程稱為對象的序列化。
把位元組序列恢複為對象的過程稱為對象的反序列化。
對象的序列化主要有兩種用途:
1) 把對象的位元組序列永久地儲存到硬碟上,通常存放在一個檔案中;
2) 在網絡上傳送對象的位元組序列。
在很多應用中,需要對某些對象進行序列化,讓它們離開記憶體空間,入住實體硬碟,以便長期儲存。比如最常見的是Web伺服器中的Session對象,當有 10萬使用者并發通路,就有可能出現10萬個Session對象,記憶體可能吃不消,于是Web容器就會把一些seesion先序列化到硬碟中,等要用了,再把儲存在硬碟中的對象還原到記憶體中。
當兩個程序在進行遠端通信時,彼此可以發送各種類型的資料。無論是何種類型的資料,都會以二進制序列的形式在網絡上傳送。發送方需要把這個Java對象轉換為位元組序列,才能在網絡上傳送;接收方則需要把位元組序列再恢複為Java對象。
serialVersionUID: 字面意思上是序列化的版本号,凡是實作Serializable接口的類都有一個表示序列化版本辨別符的靜态變量。我麼你來看一下Serializable接口中關于serialVersionUID的介紹:
它的大緻意思就是,如果類實作了Seriable接口就是可序列化的類,系統會根據類中的屬性等等預設生成一個類的序列化的版本号serialVersionUID,不過呢,不推薦,推薦顯示聲明這個類的serialVersionUID,比如,即:
private static final long serialVersionUID = 42L;
因為,如果不是顯式聲明,類的結構改變的時候,serialVersionUID就會改變,之前存儲的資料在反序列化回來的時候就會報錯,抛出異常。
建立一個實作Serializable接口的Persion序列化類,Persion.java
import java.io.Serializable;
/**
* <p>ClassName: Person<p>
* <p>Description:測試對象序列化和反序列化<p>
*/
public class Person implements Serializable {
/**
* 序列化ID
*/
private static final long serialVersionUID = -5809782578272943999L;
private int age;
private String name;
private String sex;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getSex() {
return sex;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setSex(String sex) {
this.sex = sex;
}
}
測試一下,這個類的序列化與反序列化:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.MessageFormat;
/**
* <p>ClassName: TestObjSerializeAndDeserialize<p>
* <p>Description: 測試對象的序列化和反序列<p>
*/
public class TestObjSerializeAndDeserialize {
public static void main(String[] args) throws Exception {
SerializePerson();//序列化Person對象
Person p = DeserializePerson();//反序列Perons對象
System.out.println(MessageFormat.format("name={0},age={1},sex={2}",
p.getName(), p.getAge(), p.getSex()));
}
/**
* MethodName: SerializePerson
* Description: 序列化Person對象
* @author xudp
* @throws FileNotFoundException
* @throws IOException
*/
private static void SerializePerson() throws FileNotFoundException,
IOException {
Person person = new Person();
person.setName("gacl");
person.setAge(25);
person.setSex("man");
// ObjectOutputStream 對象輸出流,将Person對象存儲到E盤的Person.txt檔案中,完成對Person對象的序列化操作
ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
new File("E:/Person.txt")));
oo.writeObject(person);
System.out.println("Person對象序列化成功!");
oo.close();
}
/**
* MethodName: DeserializePerson
* Description: 反序列Perons對象
* @author xudp
* @return
* @throws Exception
* @throws IOException
*/
private static Person DeserializePerson() throws Exception, IOException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
new File("E:/Person.txt")));
Person person = (Person) ois.readObject();
System.out.println("Person對象反序列化成功!");
return person;
}
}
編譯運作:
檢視E盤,多了一個Person.txt
注釋掉
//SerializePerson();//序列化Person對象
注釋掉
/private static final long serialVersionUID = -5809782578272943999L;
編譯運作會報錯,抛出異常,這是因為,寫入Person.txt檔案時serialVersionUID=-5809782578272943999L,系統預設的serialVersionUID=-7391400382246312552。
Exception in thread "main" java.io.InvalidClassException:
serial.Person; local class incompatible:
stream classdesc serialVersionUID = -5809782578272943999,
local class serialVersionUID = -7391400382246312552