序列化代理简单来说,A有序列化的需求,但是不直接序列化A,而是序列化一个A的代理对象B,我们可以将A的信息保存在B中,在反序列化时,再通过B得到A的信息,实例化一个A对象
为什么这么费劲呢?因为反序列化是java机制之外的东西,不通过构造方法生成实例,这样有机会被入侵(具体说不上,就是有可能被黑的意思吧),采用序列化代理可以有效的避免通过反序列化来生成实例,所有的实例都通过构造函数来生成,这样就可以保证所有的实例都遵守构造函数的约束。
具体实现呢 通过例子来说吧:
public class Dog implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 2599175554577989702L;
private String name;
private int age;
Dog(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private static class SerializationProxy implements Serializable
{
/**
*
*/
private static final long serialVersionUID = -1792022185138959673L;
private String name;
private int age;
SerializationProxy(Dog dog)
{
this.name = dog.name;
this.age = dog.age;
}
private Object readResolve()
{
return new Dog(name,age);
}
private void writeObject(ObjectOutputStream out) throws IOException
{
out.defaultWriteObject();
System.out.println("项");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
in.defaultReadObject();
System.out.println("羽");
}
}
private Object writeReplace()
{
return new SerializationProxy(this);
}
private void readObject(ObjectInputStream in) throws Exception
{
throw new Exception("proxy required");
}
}
定义了一个内部类,SerializationProxy 作为Dog 的序列化代理
如果试图序列化一个Dog,由于Dog中定义了
private Object writeReplace()
{
return new SerializationProxy(this);
}
则实际会序列化一个Dog的序列化代理,而这个序列化代理是通过Dog对象来构造的(保存了Dog的信息),上节说到,之后的过程都会依赖实际被序列化类的序列化实现,也就是会依赖于Dog序列化代理的序列化实现,反序列化Dog序列化代理时由于
private Object readResolve()
{
return new Dog(name,age);
}
实际会返回一个Dog对象,这样原来保存的Dog信息又回来了,而且新的Dog实例是通过构造方法生成的。
如何使用呢,其实完全看不出来,正常用就行了
@Test
public void testOut03() throws FileNotFoundException, IOException
{
Dog d = new Dog("小白",2);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:\\temp01.txt"));
out.writeObject(d);
out.flush();
out.close();
}
@Test
public void testIn03() throws FileNotFoundException, IOException, ClassNotFoundException
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\\temp01.txt"));
Dog d = (Dog)in.readObject();
in.close();
System.out.println(d.getAge());
System.out.println(d.getName());
}
}
用法呢其实都是相同的,关键是序列化类wirteObject和readObject的实现。