Java語言從添加枚舉中受益匪淺;但不幸的是,在具有不同代碼級別的系統之間發送序列化對象時,它們不能很好地工作。在Java中有序列化枚舉的好方法嗎?
示例:假設您有兩個系統A和B.它們都以相同的代碼級別開始,但在某個時間點開始在不同時間點查看代碼更新。現在假設有一些
public enum Whatever { FIRST; }
還有其他的對象,保持引用該枚舉的常量。這些對象被序列化並從A發送到B,反之亦然。現在考慮B具有無論新版本的
public enum Whatever { FIRST; SECOND }
然後:
class SomethingElse implements Serializable { ...
private final Whatever theWhatever;
SomethingElse(Whatever theWhatever) {
this.theWhatever = theWhatever; ..
被實例化......
SomethingElse somethin = new SomethingElse(Whatever.SECOND)
,然後串行轉換髮送到A(例如,作爲一些RMI呼叫的結果)。這是不好的,因爲現在在A的反序列化過程中會出現一個錯誤:A知道任何枚舉類,但是在沒有SECOND的版本中。
我們認爲這很難;現在我非常渴望使用枚舉來實現「完美枚舉」的情況;只是因爲我知道我以後不能輕易擴展現有的枚舉。
現在我想知道:是否有(良好的)策略避免這種與枚舉的兼容性問題?或者我真的不得不回到「前枚舉」時代;並且不要使用枚舉,但必須依靠一個解決方案,我在整個地方使用普通的字符串?
更新:請注意,使用serialversionuid根本沒有幫助。這件事只會幫助你做出不相容的變化「更明顯」。但重點是:我不關心爲什麼反序列化失敗 - 因爲我必須避免它發生。而且我也無法改變我們序列化對象的方式。我們正在做RMI;我們正在序列化爲二進制;我無法改變這種情況。
這不是任何類的問題嗎?如果您更改較新版本的字段,則舊版本的反序列化將失敗。 – 4castle
不一定。添加字段是完全有效的操作。如果你使用純字符串,你顯然會減少編譯時間檢查;但是如果一個對象字段是String,那麼這個字段可以帶**任何**值而不會引起這樣的問題。 – GhostCat
您可以使用常量 - 這些序列化很好,並且它們具有許多類枚舉屬性 –