[英]Java compatibility for serialized object read from changed class
我有這種形式的課程:
public class Foo implements Serializable {
private static final long serialVersionUID = 20130605L;
private Object fields[];
// Methods, etc.
}
一段時間以來還可以,但現在(出於可讀性和維護性考慮)已轉換為:
public class Foo implements Serializable {
private static final long serialVersionUID = 20130605L;
private String field1;
private String field2;
private Boolean fiedl3;
// Methods, etc.
}
當您使用新的類版本讀取舊文件時,就會出現問題。 如果使用其他serialVersionUID,則不兼容。 如果您使用相同的serialVersionUID,則我需要實現一些使其兼容的東西。 這是我的辦法,重寫private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
因此我可以手動檢查文件中對象的版本。
問題再次出在我想使用java.io.ObjectInputStream.defaultReadObject();
因此它會自動對下一個版本進行“魔術處理”(在新字段中為可選字段)。 所以我有這樣的事情:
public class Foo implements Serializable {
private static final long serialVersionUID = 20130605L;
private String field1;
private String field2;
private Boolean fiedl3;
// Methods, etc.
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
Object obj = in.readObject();
if (obj instanceof Object[]) {
Object[] tmp = (Object[])obj;
field1 = (String)obj[0];
field2 = (String)obj[1];
// ....
} else {
in.defaultReadObject();
}
}
}
問題是,因為我已經讀取了部分流,所以defaultReadObject方法崩潰。
我正在搜索一個Stream,該Stream可以讓您兩次讀取一個對象,但找不到。 我也知道我可以完全手動進行讀取,但是每次添加另一個字段時,我都需要對此進行修改(在defaultReadObject
,由於它寫入字段名稱,因此只能還原自動讀取的字段)。
所以我的問題是“我怎么做?
注意:我只需要兼容性是為了從新類讀取舊類對象,並從新類對象讀取新類對象。 我也讀過其他問題,但他們只回答了如何計划一個具有后衛兼容性的好班級(我應該在:-(之前讀過它)。
我發現的唯一解決方案是維護對舊字段的引用。 請注意,您可以將其設置為transient
因為這樣一來它就不會被讀取,因此您必須永遠攜帶它。
public class Foo implements Serializable {
private static final long serialVersionUID = 20130605L;
private Object fields[]; // So we can read it in old saved version.
private String field1;
private String field2;
private Boolean fiedl3;
// Methods, etc.
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
if (fields != null) {
// If we have read an old version.
field1 = (String)fields[0];
field2 = (String)fields[1];
field3 = (Boolean)fields[2];
// ....
// We set fields to null so no more space is waste than necessary.
fields = null;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.