我正在阅读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
,因为它应该如此?
答案 0 :(得分:3)
因为您正在返回this
,而不是替换对象,并且this
已经是正确的类型,按照定义。
通常,当您使用此方法时,它将与writeReplace()
方法结合使用,该方法将返回要序列化的其他对象,并且其义务是使用readResolve()
方法返回原始类型的对象。你不是在这里做的,所以你真正在做的是以一种相当无意义的方式滥用readResolve()
,这也可以在一个自定义readObject()
方法中完成,而不会提出像此