Java 序列化

2022-09-08 12:04:41

Java 序列化

當一個物件需要持久化(儲存)或者傳輸的時候,就用到了序列化。物件可以轉換成位元組序列,該位元組序列包括這個物件的資料和型別資訊也包括儲存在物件中資料的型別。

將序列化物件持久化(寫入檔案)之後,可以從持久化的媒介(檔案)中讀取出來,並且對它進行反序列化,也就是說,物件的型別資訊、物件的資料,還有物件中的資料型別以及方法,都可以用來在記憶體中新建物件。

整個過程都是 Java 虛擬機器器(JVM)獨立的,也就是說,在一個平臺上序列化的物件可以在另一個完全不同的平臺上反序列化該物件。

 

一個類的物件要想序列化成功,必須滿足兩個條件:

1、該類必須實現 java.io.Serializable 介面。(Serializable是一個標記介面,沒有需要實現的方法。標記介面別名《Marker Interface》和《Tag interface》)

2、該類的所有屬性必須是可序列化的。如果有一個屬性不是可序列化的,則該屬性必須註明是短暫的(transient)。

如果你想知道一個 Java 標準類是否是可序列化的,請檢視該類的檔案。檢驗一個類的範例是否能序列化十分簡單, 只需要檢視該類有沒有實現 java.io.Serializable介面。

 

序列化和反序列化 Demo

用 FileOutputStream 和 ObjectOutputStream 類來序列化物件,並將該物件序列化到一個檔案中。

再用 FileInputStream 和 ObjectInputStream 類來從檔案中讀取,並反序列化這個物件。

注意: 按照 Java 的標準約定是給檔案一個 .ser 擴充套件名,但是實際只要符合檔案命名規則就可以序列化。

/**
 * 物件的序列化和反序列化
 */
public class ObjectSerializeDemo implements Serializable {

    private int old = 8;
    String name = "tianjun";
    transient String address = "北京";
    Number phone;

    void print() {
        System.out.println(String.format("name=%s; old=%d; phone=%d; address=%s", name, old, phone, address));
    }

    public static void main(String[] args) {
        ObjectSerializeDemo tj = new ObjectSerializeDemo();
        tj.phone = 123456789;
        tj.old = 18;
        tj.address = "石家莊";

        System.out.println("需要序列化的物件");
        tj.print();

        System.out.println("序列化");
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("e:\\tj.s");
            try {
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
                objectOutputStream.writeObject(tj);
                objectOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println("====================================");
        System.out.println("反序列化");
        try {
            FileInputStream fileInputStream = new FileInputStream("e:\\tj.s");
            try {
                ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
                try {
                    ObjectSerializeDemo o = (ObjectSerializeDemo) objectInputStream.readObject();

                    System.out.println("反序列化後的物件");
                    o.print();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}

輸出內容如下:

  需要序列化的物件
  name=tianjun; old=18; phone=123456789; address=石家莊
  序列化
  ====================================
  反序列化
  反序列化後的物件
  name=tianjun; old=18; phone=123456789; address=null

注意:address 註明了transient,所以反序列化後=null