序列化接口的id的作用


對象經常要通過IO進行傳送,讓你寫程序傳遞對象,你會怎么做?把對象的狀態數據用某種格式寫入到硬盤,Person->“zxx,male,28,30000”Person,既然大家都要這么干,並且沒有個統一的干法,於是,sun公司就提出一種統一的解決方案,它會把對象變成某個格式進行輸入和輸出,這種格式對程序員來說是透明(transparent)的,但是,我們的某個類要想能被sun的這種方案處理,必須實現Serializable接口。

       ObjectOutputStream.writeObject(obj);

       Object obj = ObjectInputStream.readObject();

       假設兩年前我保存了某個類的一個對象,這兩年來,我修改該類,刪除了某個屬性和增加了另外一個屬性,兩年后,我又去讀取那個保存的對象,或有什么結果?未知!sun的jdk就會蒙了。為此,一個解決辦法就是在類中增加版本后,每一次類的屬性修改,都應該把版本號升級一下,這樣,在讀取時,比較存儲對象時的版本號與當前類的版本號,如果不一致,則直接報版本號不同的錯!

 

  簡單來說,Java的序列化機制是通過在運行時判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體(類)的serialVersionUID進行比較,如果相同就認為是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常。

     當實現java.io.Serializable接口的實體(類)沒有顯式地定義一個名為serialVersionUID,類型為long的變量時,Java序列化機制會根據編譯的class自動生成一個serialVersionUID作序列化版本比較用,這種情況下,只有同一次編譯生成的class才會生成相同的serialVersionUID 。

如果我們不希望通過編譯來強制划分軟件版本,即實現序列化接口的實體能夠兼容先前版本,未作更改的類,就需要顯式地定義一個名為serialVersionUID,類型為long的變量,不修改這個變量值的序列化實體都可以相互進行串行化和反串行化。

    以上兩段話摘自http://blog.sina.com.cn/s/blog_3e9d2b3501011uy8.html,以前只知道序列化ID的此作用,但實際並未碰到過。昨天有幸一見,現把場景回憶如下:

    環境:

    1)分布式即多台resin服務器;

    2)序列化的java類沒有顯示定義serialVersionUID;

    3)使用了Redis作為緩存(序列化后的對象存入redis緩存中);

    在使用過程,報序列化時候版本不兼容,即serialVersionUID不同異常。由於不顯示定義serialVersionUID,在分布式環境,相同類的class在不同resin在的class的serialVersionUID不同,反序列化就容易報此異常。

    所以,在使用序列化過程中,最好顯示定義序列號。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM