当只有子类实现可序列化时,序列化如何工作

只有子类实现了Serializable接口。

 import java.io.*; public class NewClass1{ private int i; NewClass1(){ i=10; } int getVal() { return i; } void setVal(int i) { this.i=i; } } class MyClass extends NewClass1 implements Serializable{ private String s; private NewClass1 n; MyClass(String s) { this.s = s; setVal(20); } public String toString() { return s + " " + getVal(); } public static void main(String args[]) { MyClass m = new MyClass("Serial"); try { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serial.txt")); oos.writeObject(m); //writing current state oos.flush(); oos.close(); System.out.print(m); // display current state object value } catch (IOException e) { System.out.print(e); } try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("serial.txt")); MyClass o = (MyClass) ois.readObject(); // reading saved object ois.close(); System.out.print(o); // display saved object state } catch (Exception e) { System.out.print(e); } } } 

我注意到的一件事是,父类没有序列化。 然后,为什么它没有抛出NotSerializableException确实它显示以下

产量

 Serial 20 Serial 10 

此外,输出与SerializationDe-serialization 。 我只是知道,这是因为父类没有实现Serializable 。 但是,如果有人解释我,在对象序列化和反序列化过程中会发生什么。 它如何改变价值? 我无法弄清楚,我也在我的程序中使用了评论。 所以,如果我在任何时候都错了,请告诉我。

根据Serializable javadoc

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

此外,如果被序列化的类不可序列化,则仅抛出序列化exception。 有不可序列化的父母是好的(只要他们有一个no-arg构造函数)。 对象本身不是Serializable,一切都扩展了它。 上面的引用也解释了为什么你得到值字段的不同值 – 设置了父类的no-arg构造函数,它将值字段设置为10 – 该字段属于(不可序列化的)父类,因此其值不是写入/从流中读取。

如果MyClass持有对非可序列化类的对象的引用,则在运行时将获得NotSerializableexception。 要进行测试,请修改MyClass,使其保存对NewClass1对象的引用。 如果再次运行,它将抛出exception。

反序列化实质上是创建可序列化类的实例并恢复其属性。 在此过程中,不会调用可序列化类的构造函数。 而是调用第一个非可序列化超类的无参数构造函数。

在你的情况下,NewClass1的no arg构造函数将10分配给它的实例变量i。 因此,在反序列化期间,它打印10而不是20。

我没有测试它,但如果序列化基类的实例,你将得到一个NotSerializableException 。 当您的类包含一些不可Serializable成员时,它们是相同的。

表示如果创建对象NewClass1 nc1 = new NewClass1(); 并尝试序列化obj nc1,您将获得所需的exception。