Serializable 、序列化、反序列化、衝突

概念

序列化:將實體對象轉換爲字節序列。

反序列化:將字節序列轉換爲實體對象。

作用

1、用於存儲實體對象

比如,我們要將對象數據持久化到磁盤、或者存儲在緩存中,那麼就需要先將實體對象序列化,轉爲字節序列,再將字節序列存儲。當我們要讀取對象的時候,將字節序列讀取出,反序列化,轉換爲實體對象。

2、用於網絡傳輸

比如,當一個Java端將實體對象網絡傳輸到另一個Java端的時候,首先需要將對象序列化,轉換爲字節序列,將字節序列通過網絡傳輸到另一個Java端上,Java端接收到字節序列時,進行反序列化,轉換爲實體對象。

Serializable 接口

public interface Serializable {           }

這是一個空接口,但是我們在定義類的時候,如果需要持久化或者網絡傳輸的話,就要將我們的類實現這個接口,可是這是個空的接口,怎麼起作用呢?

我們的類實現了這個接口,這個接口只做一個標識作用,告訴我們的程序,這個類的實例化對象能被序列化。

 serialVersionUID 變量

我們的類實現了Serializable接口後,serialVersionUID出現了三種情況:

1. 我們不顯示定義 serialVersionUID的值

JDK會根據類的信息自動生成一個,缺點:不同的JDK版本,可能對同一個類會生成不同的serialVersionUID,這樣會導致反序列化失敗。

2. 我們顯示定義serialVersionUID 的值

開發工具會有這個功能,自動在我們的類裏面添加一個隨機的serialVersionUID,這樣就不會因爲JDK版本導致反序列化失敗了。 缺點:每一個類都被唯一的serialVersionUID 所標識,那麼如果一個父類,一個子類,這兩個類的serialVersionUID肯定不一樣,此時,我們要想

3. 我們顯示定義serialVersionUID = 1L

一般情況下,如果我們不要求serialVersionUID的唯一性的話。

相關bug

序列化出錯的問題:local class incompatible: stream classdesc serialVersionUID = 1, stream classdesc serialVersionUID = 2427389723552147596

serialVersionUID的作用:Java通過這個屬性來反序列化對象 和 反序列化類 的版本是否一致,一致的情況下,才允許進行反序列化。

假設一個場景:Java端將實體對象(類爲AAAA)發送並存到redis數據庫中。

class AAAA implements Serializable{  },Java端將對象序列化,此時沒有顯示指定serialVersionUID的值,所以JDK會默認根據這個類的信息生成一個serialVersionUID,將序列化後的字節序列發送到redis,redis接收到後存起來;第二次Java端修改了AAAA的代碼(這就意味着serialVersionUID變了,因爲AAAA的信息變了,JDK爲它默認生成的serialVersionUID也就變了),然後運行起來,去redis讀取之前存的對象,發現對象裏的serialVersionUID 和 AAAA類的serialVersionUID不一樣了,那麼自然不允許進行反序列化,所以無法將字節序列轉換爲對象。(這就是反序列化失敗)

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