如何在序列化和反序列化过程中调用构造函数?

如何在序列化和反序列化过程中调用构造函数

  1. 什么时候有一个类实现可序列化?
  2. 当有父母/子女关系,只有孩子实现可序列化?
  3. 当有父母/子女关系,父母双方都实现可串行化?

例:

public class ParentDeserializationTest { public static void main(String[] args){ try { System.out.println("Creating..."); Child c = new Child(1); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); c.field = 10; System.out.println("Serializing..."); oos.writeObject(c); oos.flush(); baos.flush(); oos.close(); baos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); System.out.println("Deserializing..."); Child c1 = (Child)ois.readObject(); System.out.println("c1.i="+c1.getI()); System.out.println("c1.field="+c1.getField()); } catch (IOException ex){ ex.printStackTrace(); } catch (ClassNotFoundException ex){ ex.printStackTrace(); } } public static class Parent { protected int field; protected Parent(){ field = 5; System.out.println("Parent::Constructor"); } public int getField() { return field; } } public static class Child extends Parent implements Serializable{ protected int i; public Child(int i){ this.i = i; System.out.println("Child::Constructor"); } public int getI() { return i; } } 

}

输出:

 Creating... Parent::Constructor Child::Constructor Serializing... Deserializing... Parent::Constructor c1.i=1 c1.field=5 

所以如果你反序列化你的对象,它的构造函数不会调用,但是它的父类的默认构造函数将被调用。 不要忘记:所有可序列化的对象应该有一个没有参数的标准构造函数。

在反序列化过程中,为inheritance层次结构中的第一个类调用了可访问的默认构造函数,该类没有实现Serializable。

>一个Serializable类必须能够访问它的第一个不可序列化的超类的no-arg构造函数

  1. 如果要精确一点,就没有“一个阶级”这样的东西。 Java中的每个对象都会扩展类Object,无论它是直接的超类还是其层次结构的间接根。 所以没有构造函数会运行,但假装是这样,那么我们不是重新创build一个对象,而是创build一个新对象。

  2. 有父母/子女关系时,取决于父母是否可序列化。 如果父级不是可序列化的,超级构造函数将运行! 如果父类和子类都是可序列化的,则不会调用构造函数。

更多信息?

http://www.java-questions.com/Serialization_interview_questions.html

如何在序列化和反序列化过程中调用构造函数

  1. 什么时候有一个类实现可序列化?

  2. 当有父母/子女关系,只有孩子实现可序列化?

  3. 当有父母/子女关系,父母双方都实现可串行化?

在我看来,你的问题的答案是:

1)如果一个类正在实现序列化,只有那个类没有父类。 构造函数stream就像默认构造函数一样,将调用未实现可序列化的父类。 在这种情况下它是Object类。 所以Object类的No-arg构造函数将运行并创builddummy对象,同时调用readObject()字段将通过保存在内存或文件中的reflection和数据进行设置。

2)如果只有子类实现了可序列化,那么stream将一直持续到不可序列化的基类。 如果正确的基类没有序列化,那么(该类应该有NO-Arg构造函数)在这种情况下,NO-Arg构造函数将为基类运行。

3)如果所有的父母都被序列化,那么stream程将转到Object类,而No-Arg构造器将运行Object类。

注意:但是你可以通过实现可以外部化的接口进行序列化,那么在反序列化过程中,默认的构造函数(NO-ARG)将被调用,而不是父类的调用。