簡單來說,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不同,反序列化就容易報此異常。
所以,在使用序列化過程中,最好顯示定義序列號。