為什麼Java需要物件的序列化

zbk_pointer發表於2019-03-14

1,什麼是序列化

序列化 (Serialization)是將物件的狀態資訊轉換為可以儲存或傳輸的形式的過程。在序列化期間,物件將其當前狀態寫入到臨時或永續性儲存區。

2,Java的序列化

將JOPO轉換成位元組流

3,Java序列化的意義(為什麼需要序列化)

  • 將物件流化,更易在通道上傳輸或者儲存在檔案中
  • 網路基礎結構和硬碟這些硬體元件能夠理解bits和bytes,但不瞭解Java物件
  • 這類似於語音通過PSTN電話線傳輸的原理

4,形象例子

經過多年的努力,地球科學家開發出一種可以幫助他們日常工作的機器人。但是這個機器人的功能比火星行星科學家開發的機器人要少。
在兩個行星的科學家會面後,火星將用飛船他們的機器人送到地球。但是問題來了。向地球傳送100臺機器人的費用為1億美元。旅行大約需要60天。
最後,火星的科學家決定與地球科學家分享他們的祕密。這個祕密是關於機器人(類比Java中的class)的結構。地球科學家在地球上開發了相同的結構。 火星的科學家將每個機器人的資料序列化並將其傳送到地球。地球科學家對資料進行反序列化並相應地將其輸入給每個機器人。這個過程節省了他們傳遞大量資料的時間。
一些機器人被用於火星上的一些防禦工作。因此,在將資料傳送到地球之前,將這些機器人的一些重要特性標記為瞬態。請注意,在物件進行反序列化時,瞬態屬性設定為null(在引用的情況下)或預設值(在基本型別的情況下)。
地球科學家注意到的另一點是,火星的科學家要求他們建立一些靜態變數來儲存環境細節。一些機器人使用這些細節。但是火星的科學家並沒有分享這些細節。因為地球的環境與火星的環境不同。即使瞭解機器人類結構並具有序列化資料,地球科學家也無法對可以使機器人工作的資料進行反序列化。

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

火星的科學家們正在等待全部付款。 付款完成後,再與地球科學家分享了serialversionUID。 地球科學家把它設定為機器人類,一切都開始工作了。

PS:
雖然在序列化的幫助下,他們能夠使用訊號而不是實際的太空船傳送資料,他們意識到傳送大量資料仍然是一個挑戰。 序列化使流程更便宜,更快,但仍然很慢。 因此,不同的科學家提出了不同的想法來減少資料量。 一些科學家建議壓縮資料,有些建議使用不同的機制來表示它,以便可以反序列化。比如XMLJSONmsgpack等。
5,應用

  1. 儲存資料以供日後使用。例如,假設您正在編寫視訊遊戲。你的程式不會永遠執行;即使它永遠不會崩潰(希望是這種情況),使用者可能會在某個時刻退出程式,或者作業系統可能會終止程式以節省資源(例如,在Android上,使用者未與之互動的後臺程式經常並故意被作業系統殺死以回收RAM等系統資源。為了確保使用者從一開始就沒有啟動,而是可以從最近的儲存點恢復,需要將遊戲狀態寫入持久儲存(即硬碟驅動器,使用者的Google雲端硬碟帳戶等)。為此,需要將表示遊戲狀態的記憶體中的資料結構轉換為可寫入磁碟的原始位元組(或者儲存資料的任何系統)。
  2. 從遠端伺服器取回資訊。繼續遊戲示例…假設正在建立一個線上多人遊戲,或者能夠在遊戲中提供新級別或專案而無需使用者更新其應用程式。為此,從伺服器計算機(用作各種裝置上安裝的應用程式的所有副本的聯絡點)傳達有關線上播放器的資訊或有關新級別/專案的資訊到應用程式的各個副本。伺服器和應用程式都需要這些資料結構的某種記憶體表示(例如,其他玩家的位置,新級別的結構,新專案的描述/影象等),但是要傳輸資訊從伺服器到裝置上的應用程式,通訊系統由原始位元組組成,因此有必要將資料轉換為原始位元組並將原始位元組轉換回有意義的記憶體資料結構。

相關文章