local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2427389723552147596
該錯產生來自三個原因:
1.沒有指定值:BEAN沒有指定序列化值即由JDK給出,客戶、服務端使用了不同版本的JDK。
=》解決:要使用相同JDK
2.沒有指定值:某個類在與之對應的對象已經序列化出去后做了修改,而這個屬性值由JVM根據類的相關信息計算,而修改后的類的計算結果與修改前的類的計算結果往往不同,從而造成對象的反序列化因為類版本不兼容而失敗。
=》解決:要同時重啟應用升級
3.指定值了:客戶端BEAN和服務端的BEAN里面序列化值不同。
=》解決:最好指定,在JDK中,可以利用JDK的bin目錄下的serialver.exe工具產生這個serialVersionUID,對於Test.class,執行命令:serialver Test。
在《談原型模式還有JAVA克隆還有Transient》時用到對象流,能夠被寫進對象流的的類都必須標記一個接口序列化。
用eclipse的話,會看到一個編譯警告:
那么這個變量是干啥的呢?
serialVersionUID是一個用來版本控制的UID。具體可以參考這篇文章《Understand the serialVersionUID》和相關的JSL
這篇隨筆為該文章的閱讀筆記。
要測試serialversionUID的版本控制功能,很簡單。寫三個類:
一個序列化類。
一個寫對象流的類。
一個讀對象流的類。
當被讀取的對象和當前的序列化類的UID不同時會報錯。例如:
如果不給定一個UID,JVM會自動生成一個。例如上面的錯誤是產生於下面兩段代碼:
private static final long serialVersionUID = 1L;
}
}
默認自動生成的UID,有什么壞處呢?不同環境JVM對同一個類生成的UID可能會不同,從而產生錯誤。所以說采用分布式的技術或者把對象保存到數據庫時應該要注意
序列化和反序列化的異常情況
private static final long serialVersionUID = -7755162995496909499L;
解決方式就是在實體bean 中加入上述一行代碼。
保證在bean 中增加屬性,不會導致,歷史序列化對象的反序列化 版本號不一致的情況
demo:
1 alter table `e_ybnsr_zzs_zb_gridlb` add `valid_flag` bigint DEFAULT '0' comment '0 失效 1 有效'
alter table `e_ybnsr_zzs_zb_gridlb` drop valid_flag
