1. 程式人生 > >Java學習之序列化

Java學習之序列化

序列化

Java提供了一種物件序列化的機制,該機制中,一個物件可以被表示為一個位元組序列,該位元組序列包括該物件的資料、有關物件的型別的資訊和儲存在物件中的資料的型別。

序列化儲存資料的優點

序列化的檔案更容易讓程式回覆到原來的狀態,同時序列化的檔案比較安全,因為它不是原本的內容,而是經過了編碼處理的。

Java中序列化的實現

Java中實現序列化和反序列化的類分別是ObjectOutputStream和ObjectInputStream。

ObjectOutputStream序列化方法:

public final void writeObject(Object x) throws IOException

ObjectInputStream反序列方法:

public final Object readObject() throws IOException,ClassNotFoundException

該方法從流中取出下一個物件,並將物件反序列化。它的返回值是Object,因此,你需要將它轉換成合適的資料型別。

程式碼舉例:

Employee類

package JavaReview.FileIO;

import java.io.Serializable;
//被序列化的類必須實現 java.io.Serializable 物件
public class Employee implements Serializable {
    public String name;
    public String address;
    //SSN不被序列化
    public transient int SSN;
    public int number;

    public Employee(String name, String address, int SSN, int number) {
        this.name = name;
        this.address = address;
        this.SSN = SSN;
        this.number = number;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", SSN=" + SSN +
                ", number=" + number +
                '}';
    }
}

實現序列化和反序列化

package JavaReview.FileIO;

import java.io.*;


public class SerializeDemo {
    public static void main(String[] args) {
        Employee ee=new Employee("張三","中國北京市",12312,111);
        try {
            //FileOutputStream用於把位元組寫入檔案
            FileOutputStream outfileStream=new FileOutputStream("example.ser");
            //ObjectOutputStream用於將物件進行序列化
            ObjectOutputStream os=new ObjectOutputStream(outfileStream);
            os.writeObject(ee);
            os.close();
            outfileStream.close();
            System.out.println("寫入檔案成功");
            FileInputStream infileStream=new FileInputStream("example.ser");
            ObjectInputStream is=new ObjectInputStream(infileStream);
            Employee e2=null;
            e2=(Employee) is.readObject();
            System.out.println(e2.toString());
        }catch (IOException e) {
            e.printStackTrace();
        }catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }
}

執行結果

寫入檔案成功
Employee{name='張三', address='中國北京市', SSN=0, number=111}

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

  1. 該類必須實現 java.io.Serializable 物件。
  2. 該類的所有屬性必須是可序列化的。如果有一個屬性不是可序列化的,則該屬性必須用transient關鍵詞註明是短暫的。

上述例子中,當物件被序列化時,屬性 SSN 的值為 111222333,但是因為該屬性是短暫的,該值沒有被髮送到輸出流。所以反序列化後 Employee 物件的 SSN 屬性為 0。

序列化和反序列化都需要放到try/catch中進行操作。反序列化要考慮讀取的檔案不存在的情況,所以需要新增ClassNotFoundException異常。 FileOutputStream/FileInputStream能夠將位元組寫入/讀出檔案中,但是我們通常不會直接寫位元組,而是以物件層次的觀點來寫入,所以需要高層的連線串流,類 ObjectInputStream 和 ObjectOutputStream 就是高層次的資料流,能夠將物件轉變成位元組流。