一個(gè)大的應(yīng)用程序需要使用很多的對(duì)象,由于虛擬機(jī)內(nèi)存有限,有時(shí)不可能將所有有用的對(duì)象都放在內(nèi)存中,因此,需要將不常用的對(duì)象暫時(shí)持久化到文件中,當(dāng)需要使用該對(duì)象時(shí),再從文件中把對(duì)象恢復(fù)到內(nèi)存,這就是對(duì)象的序列化和反序列化。
關(guān)鍵技術(shù):
Today:
Sun Jul 30 11:49:38 CST 2006
5 6 0 8
關(guān)鍵技術(shù):
- 需要被序列化的對(duì)象必須實(shí)現(xiàn)java.io.Serializable接口,盡管該接口沒有定義任何方法。
- 對(duì)象輸出流ObjectOutputStream可以將對(duì)象寫入到流中,通過文件輸出流可以構(gòu)造ObjectOutputStream對(duì)象。寫對(duì)象到文件時(shí)調(diào)用writeObject方法。
- 對(duì)象輸入流ObjectInputSteam可以從流中讀取對(duì)象到內(nèi)存,通過文件輸入流可以構(gòu)造ObjectInputStream對(duì)象。從文件讀對(duì)象到內(nèi)存時(shí)調(diào)用readObject方法,返回一個(gè)Object對(duì)象。
- 序列化時(shí),transient變量和類變量(靜態(tài)變量)不會(huì)被序列化。
- 序列化時(shí),對(duì)象按照writeObject方法的調(diào)用順序存儲(chǔ)在文件中,先被序列化的對(duì)象的數(shù)據(jù)在文件的前面,后被序列化的對(duì)象的數(shù)據(jù)在文件的后面。因此,在反序列化時(shí),先讀到得對(duì)象肯定是先被序列化的對(duì)象。
package book.io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
/**
* 序列化和反序列化對(duì)象
*/
public class SerializeObject {
// 一個(gè)內(nèi)部類,用于被序列化和反序列化。
//一定要實(shí)現(xiàn)Serializable才能夠被序列化和反序列化。
static class MyClass implements Serializable{
//一般的實(shí)例變量會(huì)被序列化和反序列化
private int a,b;
//transient實(shí)例變量 不會(huì) 被序列化和反序列化
private transient int c;
// 類變量 不會(huì) 被序列化和反序列化
private static int d;
public MyClass(){
}
public MyClass(int a, int b, int c, int d){
this.a = a;
this.b = b;
this.c = c;
MyClass.d = d;
}
public String toString(){
return this.a + " " + this.b + " " + this.c + " " + MyClass.d;
}
}
/**
* 序列化對(duì)象到文件
*/
public static void serialize(String fileName) throws Exception{
//創(chuàng)建一個(gè)對(duì)象輸出流,將對(duì)象輸出到文件
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName));
//序列化一個(gè)字符串對(duì)象到文件
out.writeObject("Today:");
//序列化當(dāng)前日期對(duì)象到文件
out.writeObject(new Date());
//序列化一個(gè)MyClass對(duì)象
MyClass my1 = new MyClass(5, 6, 7, 8);
out.writeObject(my1);
out.close();
}
/**
* 從文件反序列化到對(duì)象
*/
public static void deserialize(String fileName) throws Exception{
//創(chuàng)建一個(gè)對(duì)象輸入流,從文件讀取對(duì)象
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
//注意讀對(duì)象時(shí)必須按照序列化對(duì)象時(shí)的順序讀,否則會(huì)出錯(cuò)
//讀取字符串對(duì)象
String today = (String)(in.readObject());
System.out.println(today);
//讀日期對(duì)象
Date date = (Date)(in.readObject());
System.out.println(date.toString());
//讀MyClass對(duì)象,并調(diào)用它的add方法。
MyClass my1 = (MyClass)(in.readObject());
System.out.println(my1.toString());
in.close();
//當(dāng)恢復(fù)對(duì)象的時(shí)候,對(duì)象中的所有域被自動(dòng)的恢復(fù)。如果不希望某個(gè)域被序列化,可以在它前面
//加上transient關(guān)鍵字,例如下面的代碼:transient int noSer = 0;
//類似的,如果類中的某個(gè)域?yàn)殪o態(tài),它不會(huì)被序列化。
}
/**
* @param args
*/
public static void main(String[] args) throws Exception{
String fileName = "c:/temp/MyClass.ser";
SerializeObject.serialize(fileName);
//注釋掉第二行,只運(yùn)行下面一行,將會(huì)發(fā)現(xiàn)輸出不同
SerializeObject.deserialize(fileName);
}
}
運(yùn)行結(jié)果:import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
/**
* 序列化和反序列化對(duì)象
*/
public class SerializeObject {
// 一個(gè)內(nèi)部類,用于被序列化和反序列化。
//一定要實(shí)現(xiàn)Serializable才能夠被序列化和反序列化。
static class MyClass implements Serializable{
//一般的實(shí)例變量會(huì)被序列化和反序列化
private int a,b;
//transient實(shí)例變量 不會(huì) 被序列化和反序列化
private transient int c;
// 類變量 不會(huì) 被序列化和反序列化
private static int d;
public MyClass(){
}
public MyClass(int a, int b, int c, int d){
this.a = a;
this.b = b;
this.c = c;
MyClass.d = d;
}
public String toString(){
return this.a + " " + this.b + " " + this.c + " " + MyClass.d;
}
}
/**
* 序列化對(duì)象到文件
*/
public static void serialize(String fileName) throws Exception{
//創(chuàng)建一個(gè)對(duì)象輸出流,將對(duì)象輸出到文件
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName));
//序列化一個(gè)字符串對(duì)象到文件
out.writeObject("Today:");
//序列化當(dāng)前日期對(duì)象到文件
out.writeObject(new Date());
//序列化一個(gè)MyClass對(duì)象
MyClass my1 = new MyClass(5, 6, 7, 8);
out.writeObject(my1);
out.close();
}
/**
* 從文件反序列化到對(duì)象
*/
public static void deserialize(String fileName) throws Exception{
//創(chuàng)建一個(gè)對(duì)象輸入流,從文件讀取對(duì)象
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
//注意讀對(duì)象時(shí)必須按照序列化對(duì)象時(shí)的順序讀,否則會(huì)出錯(cuò)
//讀取字符串對(duì)象
String today = (String)(in.readObject());
System.out.println(today);
//讀日期對(duì)象
Date date = (Date)(in.readObject());
System.out.println(date.toString());
//讀MyClass對(duì)象,并調(diào)用它的add方法。
MyClass my1 = (MyClass)(in.readObject());
System.out.println(my1.toString());
in.close();
//當(dāng)恢復(fù)對(duì)象的時(shí)候,對(duì)象中的所有域被自動(dòng)的恢復(fù)。如果不希望某個(gè)域被序列化,可以在它前面
//加上transient關(guān)鍵字,例如下面的代碼:transient int noSer = 0;
//類似的,如果類中的某個(gè)域?yàn)殪o態(tài),它不會(huì)被序列化。
}
/**
* @param args
*/
public static void main(String[] args) throws Exception{
String fileName = "c:/temp/MyClass.ser";
SerializeObject.serialize(fileName);
//注釋掉第二行,只運(yùn)行下面一行,將會(huì)發(fā)現(xiàn)輸出不同
SerializeObject.deserialize(fileName);
}
}
Today:
Sun Jul 30 11:49:38 CST 2006
5 6 0 8
-- 學(xué)海無涯