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

          當序列化遇到繼承時……

          Posted on 2007-03-09 22:44 chenweicai 閱讀(465) 評論(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();
          ?}
          }

          測試成功!


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


          網站導航:
           
          主站蜘蛛池模板: 肇州县| 克东县| 汽车| 怀宁县| 锦州市| 麟游县| 龙江县| 九寨沟县| 日照市| 日土县| 天水市| 舒城县| 长岛县| 沈阳市| 滨海县| 伊春市| 滦南县| 蒙自县| 油尖旺区| 禄丰县| 眉山市| 衢州市| 正定县| 乌拉特中旗| 宁武县| 遂溪县| 台安县| 江安县| 行唐县| 上饶市| 凤山市| 芜湖县| 师宗县| 怀来县| 平舆县| 贺州市| 宜宾市| 遵义市| 四川省| 岗巴县| 潼关县|