请有人解释为什么在反序列化后调用类'Gambler'的构造函数但是说'Player'类的构造函数不是吗?
import java.io.*;
class Gambler {
Gambler() { System.out.print("d"); }
}
class Person extends Gambler implements Serializable {
Person() { System.out.print("c"); }
}
class Player extends Person {
Player() { System.out.print("p"); }
}
class CardPlayer extends Player implements Serializable {
CardPlayer() { System.out.print("c"); }
public static void main(String[] args) {
CardPlayer c1 = new CardPlayer();
try {
FileOutputStream fos = new FileOutputStream("play.txt");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(c1);
os.close();
FileInputStream fis = new FileInputStream("play.txt");
ObjectInputStream is = new ObjectInputStream(fis);
CardPlayer c2 = (CardPlayer) is.readObject();
is.close();
}
catch (Exception x ) { }
}
}
答案 0 :(得分:4)
因为Gambler
类没有实现Serializable
接口。来自Serializable
的javadoc:
为了允许序列化非可序列化类的子类型,子类型可能负责保存和恢复超类型的public,protected和(如果可访问)包字段的状态。只有当它扩展的类具有可访问的no-arg构造函数来初始化类的状态时,子类型才可以承担此责任。如果不是这种情况,则声明类Serializable是错误的。将在运行时检测到错误。
在反序列化期间,将使用类的public或protected no-arg构造函数初始化非可序列化类的字段。必须可以对可序列化的子类访问no-arg构造函数。 可序列化子类的字段将从流中恢复。
答案 1 :(得分:1)
虽然案例对象树中的serializing Object Tree is persisted
最高为Person
级。
如果父类不能为任何子类序列化,现在Super()
机制就会出现。所以这就是调用Gambler
的构造函数的原因。
您可以在http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html
找到更多信息在反序列化期间,将使用类的public或protected no-arg构造函数初始化非可序列化类的字段。必须可以对可序列化的子类访问no-arg构造函数。可序列化子类的字段将从流中恢复。