posts - 51, comments - 17, trackbacks - 0, articles - 9
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          當序列化遇到繼承時……

          Posted on 2007-03-09 22:44 chenweicai 閱讀(466) 評論(0)  編輯  收藏

          當序列化遇到繼承…

          當一個父類實現Serializable接口后,他的子類都將自動的實現序列化。

          以下驗證了這一點:
          package InherSerialTest;

          import java.io.Serializable;

          public class SuperA implements Serializable {

          ?private int supervalue;

          ?public SuperA(int supervalue) {
          ??super();
          ??// TODO Auto-generated constructor stub
          ??this.supervalue = supervalue;
          ?}
          ?
          ?public int getSupervalue() {
          ??return supervalue;
          ?}

          ?public void setSupervalue(int supervalue) {
          ??this.supervalue = supervalue;
          ?}

          ?public String toString(){
          ??return "supervalue is :" + supervalue;
          ?}
          }

          package InherSerialTest;

          public class SubB extends SuperA {

          ?private int subvalue;

          ?public SubB(int supervalue, int subvalue) {
          ??super(supervalue);
          ??// TODO Auto-generated constructor stub
          ??this.subvalue = subvalue;
          ?}

          ?public int getSubvalue() {
          ??return subvalue;
          ?}

          ?public void setSubvalue(int subvalue) {
          ??this.subvalue = subvalue;
          ?}

          ?public String toString() {
          ??// TODO Auto-generated method stub
          ??return super.toString() + " ,subvalue " + subvalue;
          ?}
          ?
          }

          package InherSerialTest;

          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.ObjectInputStream;
          import java.io.ObjectOutputStream;

          public class InherSerialTest {

          ?/**
          ? * @param args
          ? */
          ?public static void main(String[] args) {
          ??// TODO Auto-generated method stub

          ??SubB sub = new SubB(100,200);
          ??
          ??try{
          ???ObjectOutputStream oos = new ObjectOutputStream(
          ?????new FileOutputStream("c:\\InherSerialTest.txt"));
          ???oos.writeObject(sub);
          ???oos.close();
          ???
          ???ObjectInputStream ois = new ObjectInputStream(
          ?????new FileInputStream("c:\\InherSerialTest.txt"));
          ???SubB sub2 = (SubB)ois.readObject();
          ???System.out.println(sub2);
          ???ois.close();
          ??}catch(Exception e){
          ???e.printStackTrace();
          ??}
          ?}

          }


          結果是:supervalue is :100 ,subvalue 200

          怎管讓子類實現序列化看起來是一件很簡單的事情,但有的時候,往往我們不能夠讓父類實現Serializable接口,原因是有時候父類是抽象的(這并沒有關系),并且父類不能夠強制每個子類都擁有序列化的能力。換句話說父類設計的目的僅僅是為了被繼承。

          要為一個沒有實現Serializable接口的父類,編寫一個能夠序列化的子類是一件很麻煩的事情。java docs中提到:

          “To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime. ”

          也就是說,要為一個沒有實現Serializable接口的父類,編寫一個能夠序列化的子類要做兩件事情:

          其一,父類要有一個無參的constructor;

          其二,子類要負責序列化(反序列化)父類的域。
          如果我們將上列中的SuperA沒有實現Serializable接口,而是在SubB類中實現Serializable接口的話,即:

          public class SuperA? {}
          public class SubB extends SuperA implements Serializable{}

          我們再次運行時,將會產生錯誤:

          java.io.InvalidClassException: InherSerialTest.SubB; no valid constructor
          ?at java.io.ObjectStreamClass.<init>(Unknown Source)
          ?at java.io.ObjectStreamClass.lookup(Unknown Source)
          ?at java.io.ObjectOutputStream.writeObject0(Unknown Source)
          ?at java.io.ObjectOutputStream.writeObject(Unknown Source)
          ?at InherSerialTest.InherSerialTest.main(InherSerialTest.java:21)

          果真如docs中所說的一樣,父類缺少無參構造函數是不行的。



          接下來,按照docs中的建議我們改寫這個例子:
          package InherSerialTest2;

          import java.io.Serializable;

          public abstract class SuperC {

          ?int supervalue;

          ?public SuperC(int supervalue) {
          ??super();
          ??// TODO Auto-generated constructor stub
          ??this.supervalue = supervalue;
          ?}
          ?
          //?父類沒有實現Serializable接口,子類要可序列化的話,父類必須要有無參構造函數
          ?public SuperC(){
          ??
          ?}

          ?public int getSupervalue() {
          ??return supervalue;
          ?}

          ?public void setSupervalue(int supervalue) {
          ??this.supervalue = supervalue;
          ?}

          ?public String toString() {
          ??// TODO Auto-generated method stub
          ??return "supervalue : " + supervalue;
          ?}

          }

          package InherSerialTest2;

          import java.io.IOException;
          import java.io.ObjectInputStream;
          import java.io.Serializable;

          import InherSerialTest.SuperA;

          public class SubC extends SuperC implements Serializable{
          ?
          ?private int subvalue;

          ?public SubC(int supervalue, int subvalue) {
          ??super(supervalue);
          ??// TODO Auto-generated constructor stub
          ??this.subvalue = subvalue;
          ?}

          ?public int getSubvalue() {
          ??return subvalue;
          ?}

          ?public void setSubvalue(int subvalue) {
          ??this.subvalue = subvalue;
          ?}

          ?public String toString() {
          ??// TODO Auto-generated method stub
          ??return super.toString() + " ,subvalue :" + subvalue;
          ?}
          ?
          ?private void writeObject(java.io.ObjectOutputStream oos)throws IOException{
          ??
          ??//先序列化對象
          ??oos.defaultWriteObject();
          ??//在序列化父類的域
          ??oos.writeInt(supervalue);
          ?}
          ?
          ?private void readObject(ObjectInputStream ois)throws IOException, ClassNotFoundException{
          ??
          ??//先反序列化對象
          ??ois.defaultReadObject();
          ??//再反序列化父類的域
          ??supervalue = ois.readInt();
          ?}
          }

          測試成功!


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 交口县| 永顺县| 大厂| 昂仁县| 柘城县| 洛川县| 浮山县| 娄烦县| 青冈县| 农安县| 静安区| 翼城县| 都匀市| 长顺县| 禹州市| 宁德市| 蒙阴县| 交口县| 格尔木市| 桂阳县| 无极县| 富民县| 敦化市| 报价| 阿坝县| 五原县| 南阳市| 建水县| 浑源县| 南溪县| 邢台县| 桐城市| 罗山县| 黄冈市| 永福县| 云梦县| 黄石市| 津市市| 永春县| 陈巴尔虎旗| 建水县|