如果父级没有no-arg构造函数,则会出现序列化问题

时间:2014-08-16 15:17:27

标签: java serialization

我尽力理解这个概念。但我无法弄清楚这件事:

如果父级没有no-arg构造函数且父级没有实现Serializable接口,那么如何序列化子类呢?

Parent.java

public class Parent {
    private String parentString;
    public Parent(String parentString) {
        this.parentString = parentString;
        parentString = "Parent";
    }
    public String getParentString(){
        return parentString;
    }
}

Child.java

public class Child extends Parent implements Serializable{
    private String childString;
    public Child(String childString) {
        super(childString);
        this.childString = childString;
    }
    public String getChildString(){
        return childString;
    }
}

TestSerialization.java

public class TestSerialization {

    public static void main(String[] args) throws IOException, ClassNotFoundException{

    Child child = new Child("Child");
    FileOutputStream fos = new FileOutputStream(new File("file.ser"));
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(child);
    oos.close();

    FileInputStream fis = new FileInputStream(new File("file.ser"));
    ObjectInputStream ois = new ObjectInputStream(fis);
    Object obj = ois.readObject();
    ois.close();

    Child castChild = (Child) obj;

    System.out.println(castChild.getParentString());
    System.out.println(castChild.getChildString());


}

}

在阅读对象时,它给了我一个异常,说java.io.InvalidClassException: test.Child; no valid constructor。如何序列化这样的对象?

3 个答案:

答案 0 :(得分:4)

如果某个对象的某个超类不是Serializable且没有no-arg构造函数,则无法直接序列化该对象。来自文档:

  

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

(强调我的)

如果你可以修改父类,那么你应该简单地添加适当的no-arg构造函数和/或让它适当地实现Serializable

如果无法修改父类,则可能需要考虑序列化代理类。您可以实现方法

Object writeReplace() throws ObjectStreamException;

在你的Child中返回一个代理对象(将被序列化而不是Child实例),并实现

Object readResolve() throws ObjectStreamException;

在代理类中返回等效的Child实例。

答案 1 :(得分:0)

从序列化常见问题If class A does not implement Serializable but a subclass B implements Serializable, will the fields of class A be serialized when B is serialized?

  

仅写出并恢复Serializable对象的字段。仅当对象具有将初始化非可序列化超类型字段的无参数构造函数时,才可以恢复该对象。如果子类可以访问超类的状态,它可以实现writeObject和readObject来保存和恢复该状态。

因此,您需要在Child中提供无参数构造函数以及可选的writeObjectreadObject

答案 2 :(得分:-1)

你真的需要两个类中的默认构造函数。此外,您必须使类Parent Serializable。

另一个建议:请看一下Parent的构造函数。在那里你重新分配参数。这将没有任何效果。