gpt4 book ai didi

从更改的类读取序列化对象的 Java 兼容性

转载 作者:行者123 更新时间:2023-12-01 14:18:57 25 4
gpt4 key购买 nike

我有一个这种形式的类:

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,但我没有找到它。我也知道我可以完全手动进行读取,但是每次添加另一个字段时,我都需要修改它(在 defaultReadObject 中,因为它写入字段名称,所以它只能恢复该字段自动读取)。

所以我的问题是“我怎样才能做到?”

注意:我只需要兼容性从新类读取旧类对象,从新类对象读取新类对象。我也读过其他问题,但他们只回答如何规划一个好的类(class)以具有后卫兼容性(我应该之前读过它:-( )。

最佳答案

我发现的唯一解决方案是维护对旧字段的引用。请注意,您可以将其设置为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;
}

}
}

关于从更改的类读取序列化对象的 Java 兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17816434/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com