1. 程式人生 > >序列化注意事項

序列化注意事項

參考《深入理解Java web 技術內幕》

1.當父類實現Serializable介面時,所有子類都可以被序列化

父類程式碼:

import java.io.Serializable;

public class SerialFather implements Serializable {

    private static final long serialVersionUID = -8234435401007920773L;

    private String fatherAttribute = "I am father!";

    @Override
    public String toString() {
        return "SerialFather{" +
                "fatherAttribute='" + fatherAttribute + '\'' +
                '}';
    }
}

子類程式碼:

public class SerialSon extends SerialFather {

    private String sonAttribute = "I am son!";

    @Override
    public String toString() {
        return "SerialSon{" +
                "sonAttribute='" + sonAttribute + '\'' +
                '}';
    }
}

測試程式碼:

import java.io.*;

public class Test {

    public static void serial(Object son) {
        ObjectOutputStream oo = null;
        try {
            oo = new ObjectOutputStream(new FileOutputStream(
                    new File("E:/SerialSon.txt")));
            oo.writeObject(son);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                oo.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static Object deSerial() {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream(
                    new File("E:/SerialSon.txt")));
            return ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        SerialSon son = new SerialSon();
        //序列化過程
        serial(son);

        //反序列化過程
        Object son2 = deSerial();
        System.out.println(son2);
    }
}

結果:

SerialSon{sonAttribute='I am son!'}

2.子類實現Serializable介面,父類沒有,父類中的屬性不能被序列化(不報錯,但是資料會丟失),子類中的屬性仍能正確序列化

 

3.如果序列化的屬性是物件,則這個物件也必須實現Serializable介面,否則會報錯

4.在反序列化時,如果物件的屬性有修改或刪減,則修改的部分屬性會丟失,但是不會報錯

5.在反序列化時,如果serialVersionUID被修改,則反序列化時會失敗

6.序列化不儲存靜態屬性

首先,我們new一個物件,然後將該物件序列化後存在檔案中

public class SerialFather implements Serializable {

  private static final long serialVersionUID = -8234435401007920773L;

  private static String fatherAttribute = "I am father!";

  @Override
  public String toString() {
    return "SerialFather{" +
        "fatherAttribute='" + fatherAttribute + '\'' +
        '}';
  }
  public static void main(String[] args) throws IOException, ClassNotFoundException {
    SerialFather father = new SerialFather();
    ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream("test"));
    oo.writeObject(father);
  }
}

接著,我們改變類中靜態屬性的值

public class SerialFather implements Serializable {

  private static final long serialVersionUID = -8234435401007920773L;

  private static String fatherAttribute = "I am son!";

  @Override
  public String toString() {
    return "SerialFather{" +
        "fatherAttribute='" + fatherAttribute + '\'' +
        '}';
  }
}

然後反序列化:

  public static void main(String[] args) throws IOException, ClassNotFoundException {
    ObjectInputStream oi = new ObjectInputStream(new FileInputStream("test"));
    SerialFather father1 =  (SerialFather)oi.readObject();
    System.out.println(father1);
  }

結果:

SerialFather{fatherAttribute='I am son!'}