序列化和反序列化

序列化和反序列化

爲何要序列化

凡是離開內存的信息都要進行序列化java

序列化最終的目的是爲了對象能夠存儲,和網絡傳輸。進行存儲和網絡傳輸的方式就是IO,而IO支持的數據格式就是字節數組後端

只把對象轉成(0和1的)字節數組還不行,由於沒有規則的字節數組咱們是沒辦法把對象的原本面目還原回來的(即拿到一堆01可是並不知道這些01表明的含義),因此咱們必須在把對象轉成字節數組的時候就制定一種規則(序列化),那麼咱們從IO流裏面讀出數據的時候再以這種規則把對象還原回來(反序列化)數組

這就比如咱們要把一棟房子從一個地方運輸到另外一個地方去,序列化就是我把房子拆成一個個的磚塊放到車子裏,而後留下一張房子原來結構的圖紙,反序列化就是咱們把房子運輸到了目的地之後,根據圖紙把一塊塊磚頭還原成房子原來面目的過程網絡

對象並不僅是存在內存中,還須要傳輸網絡,或者保存起來下次再加載出來用,因此須要Java序列化技術性能

序列化的方式

序列化只是一種拆裝組裝對象的規則,那麼這種規則確定也可能有多種多樣,好比如今常見的序列化方式有:加密

JDK(不支持跨語言)、JSON、XML、Hessian/Hessian二、Kryo(不支持跨語言)、Thrift、Protobuf、FST(不支持跨語言)對象

JAVA序列化中常見的問題

  • 問題一:static 屬性不能被序列化繼承

    緣由:序列化保存的是對象的狀態,靜態變量屬於類的狀態,所以序列化並不保存靜態變量。遞歸

  • 問題二:Transient 屬性不會被序列化接口

    transient 關鍵字的做用是控制變量的序列化,在變量聲明前加上該關鍵字,能夠阻止該變量被序列化到文件中,在被反序列化後,transient 變量的值被設爲初始值,如 int 型的是 0,對象型的是 null。

    序列化一般會用於網絡傳輸數據對象,而對象中經常會含有敏感數據,因此黑客經常會攻擊這點,攻擊手段一般是利用反序列化過程構造惡意代碼,怎麼應對這種狀況呢?可使用transient關鍵字來修飾這個屬性,這樣在反序列化以後該屬性就會爲空,若是必定要傳遞的話,可使用對稱加密或非對稱加密獨立傳輸

  • 父類、子類序列化問題

    序列化是以正向遞歸的形式進行的,若是父類實現了序列化那麼其子類都將被序列化;子類實現了序列化而父類沒實現序列化,那麼只有子類的屬性會進行序列化,而父類的屬性是不會進行序列化的。

序列化注意事項

  • 序列化對象必須實現序列化接口。
  • 序列化對象裏面的屬性是對象的話也要實現序列化接口。
  • 類的對象序列化後,類的序列化ID不能輕易修改,否則反序列化會失敗。
  • 類的對象序列化後,類的屬性有增長或者刪除不會影響序列化,只是值會丟失。
  • 若是父類序列化了,子類會繼承父類的序列化,子類無需添加序列化接口。
  • 若是父類沒有序列化,子類序列化了,子類中的屬性能正常序列化,但父類的屬性會丟失,不能序列化。
  • 用Java序列化的二進制字節數據只能由Java反序列化,不能被其餘語言反序列化。若是要進行先後端或者不一樣語言之間的交互通常須要將對象轉變成Json/Xml通用格式的數據,再恢復原來的對象。

字節碼(class文件)和序列化串

參考

https://zhuanlan.zhihu.com/p/40462507

Java序列化的過程,如何把對象轉換成字節

相關文章
相關標籤/搜索