超清晰明瞭的解釋Java序列化和反序列化

一、序列化和反序列化的定義和場景

序列化:將對象寫入到IO流中

反序列化:從IO流中恢復對象

序列化機制將實現序列化的Java對象轉化爲字節數組序列。可以使對象可以脫離程序而獨立運行

場景和要求:保存到磁盤;在網絡中傳輸。要保存到磁盤和在遠程傳輸的java對象要求都必須是可序列化的。

二、序列化和反序列化的java實現

Serializable接口

一個標記接口,不用實現任何方法。一旦實現了此接口,該類的對象就是可序列化的。

序列化步驟

1 創建ObjectOutputStream輸出流;
2 調用ObjectOutputStream對象的writeObject輸出可序列化對象。

若對象不是序列化對象,序列化是將拋出 NotSerializableException 異常

反序列化步驟

1 創建ObjectInputStream輸入流;
2 調用ObjectInputStream對象的readObject()得到可序列化對象

demo:

public class People implements Serializable {
    private String name;
    private String city;
  
    public void setCity(String city) {
        this.city = city;
    }
    public void setName(String name) {
        this.name = name;
    }
    public static void main(String[] args) {
        People people = new People();
        people.setCity("成都");
        people.setName("假老練");
        People people1 = new People();
        people1.setCity("北京");
        people1.setName("風車車");
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("object.txt");
            ObjectOutputStream os = new ObjectOutputStream(fileOutputStream);
            os.writeObject(people);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            FileInputStream fileInputStream = new FileInputStream("object.txt");
            ObjectInputStream os = new ObjectInputStream(fileInputStream);
            People peopleResult = (People) os.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如果需要序列化的類的屬性含有非基本數據類型和String類型,即引用類型,那麼該引用類型也比如可序列化。否則依然會拋出 NotSerializableException 異常

serialVersionUID的作用

Java 的序列化,通過在運行時判斷類的serialVersionUID來驗證版本一致性。

在進行反序列化時,JVM 會把傳來的字節流中的serialVersionUID與本地相應實體(類)的serialVersionUID進行比較,如果相同就認爲是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常。實測如果id一致,屬性發生較小變化,對象也會創建出來,並將屬性按屬性名對號入座。

當實現序列化的時候,建議顯式定義serialVersionUID,若不顯式定義 serialVersionUID 的值,Java 會根據類細節自動生成 serialVersionUID 的值。可能造成以下兩個問題。1.如果對類的源代碼作了修改,再重新編譯,新生成的類文件的serialVersionUID的取值有可能也會發生變化。2.類的serialVersionUID的默認值完全依賴於Java編譯器的實現,對於同一個類,用不同的Java編譯器編譯,也有可能會導致不同的serialVersionUID,即不同機器或不同版本jdk反序列化可能失敗。

總結

  1. 序列化是將對象寫入到IO字節流,反序列化是從IO字節流中恢復對象
  2. 序列化的兩個主要作用是用來存儲和網絡傳輸
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章