为什么在反序列化之后调用第一个构造函数而没有其他构造函数

时间:2012-09-07 11:17:46

标签: java serialization

请有人解释为什么在反序列化后调用类'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 ) { }
 }
}

2 个答案:

答案 0 :(得分:4)

因为Gambler类没有实现Serializable接口。来自Serializable的javadoc:

  

为了允许序列化非可序列化类的子类型,子类型可能负责保存和恢复超类型的public,protected和(如果可访问)包字段的状态。只有当它扩展的类具有可访问的no-arg构造函数来初始化类的状态时,子类型才可以承担此责任。如果不是这种情况,则声明类Serializable是错误的。将在运行时检测到错误。

     

在反序列化期间,将使用类的public或protected no-arg构造函数初始化非可序列化类的字段。必须可以对可序列化的子类访问no-arg构造函数。 可序列化子类的字段将从流中恢复。

请参阅java.io.Serializable java docs

答案 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构造函数。可序列化子类的字段将从流中恢复。