了解readResolve方法

时间:2015-12-11 07:12:28

标签: java serialization

我正在阅读J.Bloch的有效Java,现在我是关于readResolve方法的部分。

我尝试使用readResolve方法并编写了以下程序:

public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException{
try(FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis)){
        ResDerived rr = (ResDerived) ois.readObject();
        System.out.println(rr);
    }
}

包含readResove的基类:

public static class ReadResolved implements Serializable{

    private transient String def = "default";

    public ReadResolved(String def) {
        this.def = def;
    }

    private void writeObject(ObjectOutputStream ous) throws ClassNotFoundException, IOException{
        ous.defaultWriteObject();
        ous.writeObject(def);
    }

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException{
        ois.defaultReadObject();
        def = (String) ois.readObject();
    }

    public Object readResolve(){
        def = "default";
        return this;
    }
}

派生类:

public static class ResDerived extends ReadResolved{

    public ResDerived(String def) {
        super(def);
    }

    private static final long serialVersionUID = 1L;

}

运行程序会生成包含带有def = default的ReadResolver的ResDerived实例。 J.Bloch说

  

如果readResolve方法受保护或公共,而子类则受保护   不重写它,反序列化序列化的子类实例将   产生一个超类实例,这可能会导致一个   ClassCastException

为什么我的程序运行正常?为什么不生成ClassCastException,因为它应该如此?

1 个答案:

答案 0 :(得分:3)

因为您正在返回this,而不是替换对象,并且this已经是正确的类型,按照定义。

通常,当您使用此方法时,它将与writeReplace()方法结合使用,该方法将返回要序列化的其他对象,并且其义务是使用readResolve()方法返回原始类型的对象。你不是在这里做的,所以你真正在做的是以一种相当无意义的方式滥用readResolve(),这也可以在一个自定义readObject()方法中完成,而不会提出像此