实例一:简单的对象的序列化与反序列化
import java.io.Serializable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
class A implements Serializable{ //定义可序列化的类
int x; private int y;
public void setY(int i){y=i;}
public int getY(){return y;}
}
public class Ch_9_10{
public static void main (String[] args){
A a=new A(); a.x=10; a.setY(99); //先创建一个用于序列化的对象
A new_a=null; //用于引用恢复后的对象
System.out.println("待序列化的对象:属性x="+a.x+" 私有属性y="+a.getY());
try{ FileOutputStream fo=new FileOutputStream("serialObj.dat");//创建用于写入文件的流
ObjectOutputStream obj_o=new ObjectOutputStream(fo); //将对象流关联到输出文件
obj_o.writeObject(a); //将a引用的对象写入对象流,即写入文件中
obj_o.close();
FileInputStream fi=new FileInputStream("serialObj.dat");//创建用于读取文件的流
ObjectInputStream obj_i=new ObjectInputStream(fi); //将对象流关联到要读取的文件
new_a=(A)obj_i.readObject(); //从流中读取对象,并强制类型转换成A类型
obj_i.close();
} catch(Exception e){ e.printStackTrace(); }
System.out.println(" 恢复的对象:属性x="+new_a.x+" 私有属性y="+new_a.getY());
a.x=111;//旨在区分原对象和恢复的对象是两个不同的对象
System.out.println("a.x= "+a.x+" new_a.x="+new_a.x);
}
}
实例二:需使用对象图的序列化与反序列化
import java.io.Serializable;//编译正确、运行报错
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
class B {public int x;} // implements Serializable //需要implements Serializable,否则有运行时错误
class A implements Serializable{ //定义可序列化的类
int x; private int y;
transient B b; // //新增属性,用于检测能否序列化b引用的对象
public void setY(int i){y=i;}
public int getY(){return y;}
}
public class Ch_9_11{
public static void main (String[] args){
A a=new A(); a.x=10; a.setY(99); a.b=new B(); //先创建一个用于序列化的对象
a.b.x=10;
A new_a=null; //用于引用恢复后的对象
System.out.println("待序列化的对象:属性x="+a.x+" 私有属性y="+a.getY()+" b.x="+a.b.x);
try{
FileOutputStream fo=new FileOutputStream("serialObj.dat");//创建用于写入文件的流
ObjectOutputStream obj_o=new ObjectOutputStream(fo); //将对象流关联到输出文件
obj_o.writeObject(a); //将a引用的对象写入对象流,即写入文件中
obj_o.close();
}
catch(Exception e){ e.printStackTrace(); }
try{
FileInputStream fi=new FileInputStream("serialObj.dat");//创建用于读取文件的流
ObjectInputStream obj_i=new ObjectInputStream(fi); //将对象流关联到要读取的文件
new_a=(A)obj_i.readObject(); //从流中读取对象,并强制类型转换成A类型
obj_i.close();
}
catch(Exception e){ e.printStackTrace(); }
System.out.println(" 恢复的对象:属性x="+new_a.x+" 私有属性y="+new_a.getY());//+" b.x="+new_a.b.x);
}
}
实例三:用 transient 关键字避免序列化
import java.io.Serializable;//会报错,注:transient 是成员修饰符,不能修饰类
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
class C{ public int x;}
class B{ public int x; public C c;
public B(int n, C c1){x=n; c=c1; }
}
class A implements Serializable{ int x;
transient B b; //明确指明b所引用的对象将不被序列化
}
public class Ch_9_12{
public static void main (String[] args){
C c=new C(); A a=new A(); a.x=10; a.b=new B(5, c);
System.out.println("序列化前 a.b.x="+a.b.x); A new_a=null;
try{ FileOutputStream fo=new FileOutputStream("serialObj.dat");
ObjectOutputStream obj_o=new ObjectOutputStream(fo);
obj_o.writeObject(a); obj_o.close();
FileInputStream fi=new FileInputStream("serialObj.dat");
ObjectInputStream obj_i=new ObjectInputStream(fi);
new_a=(A)obj_i.readObject(); obj_i.close();
} catch(Exception e){ e.printStackTrace(); }
//注意:引用为被序列化对象的属性,会发生什么
System.out.println("恢复对象new_a.b.x="+new_a.b.x);
}
}