簡體   English   中英

跨不同JVM的Java標准庫中的SerialVersionUID

[英]SerialVersionUID in the Java standard library across different JVMs

根據此處對SerialVersionUID的描述: https ://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100,似乎有必要始終在您創建的任何類中包括SerialVersionUID,以便用於序列化的JVM和用於反序列化的不同JVM不會自動分配它們自己的SerialVersionUID,由於JVM的不同,它們可能彼此不同。 這對於控制我自己的類的反序列化效果很好,但是如果我要確保用JVM B序列化的標准庫中的類可以被JVM B反序列化,那該怎么辦?

Map<Integer, String> myMap = new HashMap<>();

HashMap定義了SerialVersionUID。 但:

  • 由於HashMap駐留在Java標准庫中,因此我是否提供任何保證,如果我使用JVM A序列化此HashMap,則JVM B可以反序列化它? 即,至少如果B只是從A的次要版本升級,是否允許JVM B指定與JVM A不同的SerialVersionUID?
  • 如果不能保證標准庫類,使用SerialVersionUID是否真的可以確保從未接觸過Java標准庫的自己的類正確地反序列化? 例如,一個看起來像這樣的類:

     public class NewClass implements Serializable { private static final long serialVersionUID = 1L; private final Map<Integer, String> myMap; public NewClass() { this.myMap = new HashMap<>(); } } 

    容易失敗,因為反序列化取決於HashMap具有相同的SerialVersionUID,在不同的JVM中可能不同,對嗎?

可能是的,您是正確的。

實際上,這在我們之前發生過,有些swing類(我真的不記得是哪一個),但是在jdkX序列化並在jdkX+1jdkX+1序列化它們(那是很久以前的事情了,很抱歉錯過了這些詳細信息),事情開始因InvalidClassException而中斷。 當時我們已經提供了支持,並提出了一個問題-答復是,這些類已經以某種方式更改,以致無法正確地反序列化它們-您受此版本困擾,或升級到jdk+1並使用它。 從那以后我就沒有發生過,甚至沒有一次。

通常,我認為,這也是使序列化變得困難的原因。 您必須維護這樣一個過程,以便從序列化的角度使將來版本中的更改變得相關並與以前的版本兼容。

另一方面, HashMap具有一種非常智能的方式來序列化其數據。 它系列化(尤其喜歡load_factor等), 只是它的鍵和值-沒有別的。 因此,無論實現如何更改,都可以將它們反序列化。 因此,某些不需要的字段被標記為瞬態,例如:

 transient int modCount;
 transient Set<Map.Entry<K,V>> entrySet;

這個想法是它應該序列化數據與結構。


如果HashMap發生變化,例如序列化將在jdk-11中斷,這將使很多開發人員感到憤怒,我懷疑這是否會是一條路(除非確實需要)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM