对象的序列化就是把一个对象变为二进制的数据流的一种方法。换言之对象的序列化可以方便的实现对象的传输和存储。
如果要一个类的对象序列化,则该类要实现java.io.Serializable接口。此接口中没有定义任何的方法只是一个标识接口。
定义一个可以序列化的类:
package com.zss0530;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private int age ;
public Student(String name ,int age ){
this.name=name;
this.age=age;
}
public String toString(){
return "姓名"+this.name+"年龄"+this.age;
}
}
如果要对对象的输入(序列化)和输出(反序列化),还要用到对象输入流(ObjectOutputStream)和对象输出流(ObjectInputStream)
package com.zss0530;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
/**
* 序列化
* @author Administrator
*
*/
public class SerialDemo {
public static void main(String args[])throws Exception{
File f=new File("d:"+File.separator+"tmp.txt");
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(f));
oos.writeObject(new Student("vladimir",20));
oos.close();
}
}
那么一个对象序列化是保存方法还是属性呢?
这里只有属性被序列化,因为方法是每个对象都具用的,但是属性就不一定相同了。
package com.zss0530;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/**
* 反序列化
* @author Administrator
*
*/
public class AntiSerialDemo {
public static void main(String args[])throws Exception{
File f=new File("d:"+File.separator+"tmp.txt");
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(f));
Object obj=ois.readObject();
ois.close();
System.out.println(obj);
}
}
实现 Serializable实际上市把一个对象的全部的属性进行序列化,但是这就
带来了一个问题,就是如果一个对象的一些属性不想被序列化。
当使用实现Serializable接口实现序列化的操作时,如果一个对象中的属性不希望被序列化,可以使用transient关键字进行声明,例如:
public class Student implements Serializable {
private transient String name;
private int age ;
public Student(String name ,int age ){
this.name=name;
this.age=age;
}
public String toString(){
return "姓名"+this.name+"年龄"+this.age;
}
}
也可实现Externalizable接口,此接口中的函数用:
public void writeExternal(ObjectOutput out);
此方法中的指定要保存的属性的信息,对象序列化时候调用
public void readExternal(ObjectIntput input);
此方法中的读取保存的被属性的信息,对象反序列化时候调用
现在只需要在Student类中加上这两个方法的实现就行了
public void writeExternal(ObjectOutput out){
out.writeObject(this.name);
out.writeInt(this.age);
}
public void readExternal(ObjectIntput input){
this.name=(String)input.readObject();
this.age=input.readInt();
}
但是要注意的是如果一个类实现了Externalizable接口后,此类中类保留一个无参构造方法,因为在反序列化是要调用。