java對象序列化和反序列化的概念

1)什麼是對象序列化和反序列化  

     把對象轉換爲 字節序列的過程稱爲 對象的序列化。
  把字節序列  恢復爲對象的過程稱爲 對象的反序列化。
  對象的序列化主要有兩種用途:
  1) 把對象的字節序列 永久地保存到硬盤上,通常存放在一個文件中;
  2) 在網絡上 傳送對象的字節序列。


2)具體使用場景  

  在很多應用中,需要對某些對象進行序列化,讓它們離開內存空間,入住物理硬盤,以便長期保存。

    比如:
    一、最常見的是Web服務器中的Session對象,當有 10萬用戶併發訪問,就有可能出現10萬個Session對象,內存可能喫不消,
    於是Web容器就會把一些seesion先序列化到硬盤中,等要用了,再把保存在硬盤中的對象還原到內存中。
   
    二、 RPC應用,比如 Dubbo hession等
  當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。   發送方需要把這個Java對象轉換爲字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢復爲Java對象。

3)怎麼使用  (JDK類庫中的序列化API)
     只有實現了Serializable和Externalizable接口的類的對象才能被序列化。
             Externalizable接口繼承自 Serializable接口, 實現Externalizable接口的類完全由自身來控制序列化的行爲,可以指定序列化哪些屬性。
            實現Serializable接口的類可以 採用默認的序列化方式 。  
  對象序列化使用 ObjectOutputStream ,具體使用步驟:
  1) 創建一個對象輸出流,它可以包裝一個其他類型的目標輸出流,如文件輸出流;
  2) 通過對象輸出流的writeObject(Object obj)方法寫到一個目標輸出流中。

  對象反序列化使用ObjectInputStream ,具體使用步驟:
  1) 創建一個對象輸入流,它可以包裝一個其他類型的源輸入流,如文件輸入流;
  2) 通過對象輸入流的readObject()方法讀取對象。
  
  3)注意點
     實現Serializable接口的類,經常會出現警告提示:

Eclipse就會有這個提示:The serializable class User does not declare a static final serialVersionUID field of type long,意思就是說讓你添加一個serialVersionUID的值。
  使用補全功能就會添加一行代碼 private static final long serialVersionUID = 1L;

 

serialVersionUID他有什麼作用呢?
   s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D​:​ ​字​面​意​思​上​是​序​列​化​的​版​本​號​,凡是實現Serializable接口的類都有一個表示序列化版本標識符的靜態變量
   Java的序列化機制是通過判斷類的serialVersionUID來驗證版本一致性的。
   在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體類的serialVersionUID進行比較,
  如果相同就認爲是一致的,可以進行反序列化, 否則就會出現序列化版本不一致的異常,即是Invalid Cast Exception。
      
      具體實例?比如我們寫rpc程序,遠端和本地都有一個類user,類都實現了Serializable,可以被序列化。遠端有一個同樣類,有一天遠端要在類上打印一下日誌,加了一行代碼,遠端程序反序列化的時候就會報 Invalid Cast Exception  。如果這兩個類都寫了serialVersionUID而且值一致就可以正常反序列化。如果不寫serialVersionUID,編譯器會根據這個類的結構(成員變量,成員變量的個數等),生成一個hash值,然後將這個值作爲serialVersionUID。所以類的結構有變化hash值就不一樣,就會出現報錯的現象。
      
     虛擬機是否允許反序列化,取決於類路徑和功能代碼是否一致,兩個類的序列化 ID 是否一致(就是 private static final long serialVersionUID = 1L) 

     除此之外還有幾點要注意:
           1 序列化保存的是對象的狀態,靜態變量屬於類的狀態,序列化並不保存靜態變量
           2 Transient 關鍵字的作用是控制變量的序列化,在變量聲明前加上該關鍵字,
           可以阻止該變量被序列化到文件中,在被反序列化後,transient 變量的值被設爲初始值,如 int 型的是 0,對象型的是 null 
           3 Java 序列化機制爲了節省磁盤空間,具有特定的存儲規則,當寫入文件的爲同一對象時,
           並不會再將對象的內容進行存儲,而只是再次存儲一份引用 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章