也就是說,要為一個沒有實現Serializable接口的父類,編寫一個能夠序列化的子類要做兩件事情:
其一、父類要有一個無參的constructor;
其二、子類要負責序列化(反序列化)父類的域。
我們將SuperC的Serializable接口去掉,而給SubC加上Serializable接口。運行後產生錯誤:
Java.lang.Error: Unresolved compilation problem:
Serializable cannot be resolved or is not a valid superinterface
at Serial.SubC.<init>(SubC.Java:15)
at Serial.Test1.main(Test1.Java:19)
Exception in thread "main"
果真如docs中所說的一樣,父類缺少無參構造函數是不行的。
接下來,按照docs中的建議我們改寫這個例子:
public abstract class SuperC {
int supervalue;
public SuperC(int supervalue) {
this.supervalue = supervalue;
}
public SuperC(){}//增加一個無參的constructor
public String toString() {
return "supervalue: "+supervalue;
}
}
public class SubC extends SuperC implements Serializable {
int subvalue;
public SubC(int supervalue,int subvalue) {
super(supervalue);
this.subvalue=subvalue;
}
public String toString() {
return super.toString()+" sub: "+subvalue;
}
private void writeObject(Java.io.ObjectOutputStream out)
throws IOException{
out.defaultWriteObject();//先序列化對象
out.writeInt(supervalue);//再序列化父類的域
}
private void readObject(Java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException{
in.defaultReadObject();//先反序列化對象
supervalue=in.readInt();//再反序列化父類的域
}
}
運行結果證明了這種方法是正確的。在此處我們用到了writeObject/ readObject方法,這對方法如果存在的話,序列化時就會被調用,以代替默認的行為(以後還要探討,先了解這麼多)。我們在序列化時,首先調用了ObjectOutputStream的defaultWriteObject,它使用默認的序列化行為,然後序列化父類的域;反序列化的時候也一樣。
歸納一下:
目的 行為
為一個實現Serializable接口的父類,編寫一個能夠序列化的子類 子類將自動的實現序列化
為一個沒有實現Serializable接口的父類,編寫一個能夠序列化的子類 1,父類要有一個無參的constructor;2,子類要先序列化自身,然後子類要負責序列化父類的域。