java中序列化與反序列化
把物件轉換為位元組序列的過程稱為物件的序列化。
把位元組序列恢復為物件的過程稱為物件的反序列化。
物件的序列化主要有兩種用途:
1) 把物件的位元組序列永久地儲存到硬碟上,通常存放在一個檔案中;
2) 在網路上傳送物件的位元組序列。
在很多應用中,需要對某些物件進行序列化,讓它們離開記憶體空間,入住物理硬碟,以便長期儲存。比如最常見的是Web伺服器中的Session物件,當有 10萬用戶併發訪問,就有可能出現10萬個Session物件,記憶體可能吃不消,於是Web容器就會把一些seesion先序列化到硬碟中,等要用了,再把儲存在硬碟中的物件還原到記憶體中。
當兩個程序在進行遠端通訊時,彼此可以傳送各種型別的資料。無論是何種型別的資料,都會以二進位制序列的形式在網路上傳送。傳送方需要把這個Java物件轉換為位元組序列,才能在網路上傳送;接收方則需要把位元組序列再恢復為Java物件。
serialVersionUID: 字面意思上是序列化的版本號,凡是實現Serializable介面的類都有一個表示序列化版本識別符號的靜態變數。我麼你來看一下Serializable介面中關於serialVersionUID的介紹:
它的大致意思就是,如果類實現了Seriable介面就是可序列化的類,系統會根據類中的屬性等等預設生成一個類的序列化的版本號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