關於Serializable的serialVersionUID

來源:互聯網
上載者:User

在實現了Serializable介面的class中,需要聲明一個long serialVersionUID,用來標明當前class的版本號碼,但很多人在編程時,總是不原意去聲明這個serialVersionUID,又JVM自己來產生。下面來看看serialVersionUID的作用:

1、如果在序列化寫 時的版本號碼和序列化讀 時的版本號碼,不一致,將會有異常:java.io.InvalidClassException:local class incompatible: stream classdesc serialVersionUID = …, local class serialVersionUID = …

2、那如果在class中不聲明這個屬性呢?那結果可以就會變得比較詭異了: 

1)、在序列化寫 的時候,虛擬機器A會為它計算出一個serialVersionUID,計算的方法是依據class的資訊,再具體我也不清楚了。

2)、在序列化讀 的時候,虛擬機器B也會為class計算出一個serialVersionUID,然後做比較。

3)、那麼如果兩個虛擬機器是不同類型的虛擬機器,那麼計算方法可能就不一樣了,於是即使相同的class,serialVersionUID也可能會不同,不同的class的,理論上來說,也存在serialVersionUID相同的可能性,所以,serialVersionUID盡量由我們自己來指定,而不要由虛擬機器來計算。

3、那如果serialVersionUID一致,而class發生了變化呢? 

1)、如果虛擬機器A中的AClass有一個屬性,而虛擬機器B中的AClass,沒有這個屬性,那麼這個屬性將被忽略,而不會有異常。

2)、如果虛擬機器A中的AClass沒有的屬性,而在虛擬機器B中多出來的屬性,那麼這個屬性將被賦予一個預設值,而不會有異常。

3)、如果虛擬機器A中的AClass有一個屬性,在虛擬機器B中的AClass也有這個屬性,但這個屬性的類型變了,比如說int變成了long,抑或其他的變化,將會有異常:java.io.InvalidClassException:incompatible types for field …

經過序列化而產生的異常都是 java.io.InvalidClassException,不會產生java.lang.ClassCastException,兩者還是有比較大的區別的,從名字上就可以看得出來。

看完你還會讓JVM自己來產生serialVersionUID嗎?你還加@SuppressWarnings("serial")嗎?在一個單機上或許看不出什麼問題,但在分散式運算、或者你需要提供jar供別人使用的時候,這個問題就會暴露。

我的另一篇文章:Java
Serializable系列化與反系列化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.