从更改的类读取序列化对象的Java兼容性
我有一个这样的班级:从更改的类读取序列化对象的Java兼容性,java,serialization,deserialization,Java,Serialization,Deserialization,我有一个这样的班级: public class Foo implements Serializable { private static final long serialVersionUID = 20130605L; private Object fields[]; // Methods, etc. } 一段时间以来,这还可以,但现在(为了可读性和维护)已经转变为: public class Foo implements Serializable {
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,我需要实现一些东西使其兼容。这是我的一个方法,overwriteprivate void readObject(java.io.ObjectInputStream in)抛出IOException,ClassNotFoundException
,这样我可以手动检查文件中的对象是什么版本
问题又来了,我想使用java.io.ObjectInputStream.defaultReadObject()
因此它会自动为下一个版本执行“魔法”(在witch中,新字段是可选的)。所以我有点像:
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方法崩溃了
我搜索了一个流,它可以让你读取一个对象两次,但我没有找到它。我也知道我可以完全手动读取,但每次添加另一个字段时,我都需要修改它(在defaultReadObject
中,当它写入字段名称时,它只能恢复自动读取的字段)
所以我的问题是,我怎样才能做到
注意:我只需要兼容性用于从新类读取旧类对象和从新类对象读取新类对象。我也读过其他的问题,但他们只回答了如何计划一个好的类,使其具有backguard兼容性(我以前应该读过:-().我找到的唯一解决方案是保留对旧字段的引用。请注意,您可以将其设置为“瞬态”,因为这样它就不会被读取,因此您必须永远携带它
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;
}
}
}