考虑以下情况,问题How can I deserialize the object, if it was moved to another package or renamed?由dma_k描述:
有一个序列化文件,由旧版本的应用程序创建。不幸的是,已经序列化了类的包已更改。现在我需要将此文件中的信息加载到同一个类中,但位于不同的包中。此类已定义serialVersionUID且未更改(即兼容)。
问题是:是否可以使用任何技巧从该文件加载新的类实例(除了将类复制到旧包中然后使用反序列化包装器逻辑)? ...
解决方案是Igor Nardin的“类HackedObjectInputStream扩展ObjectInputStream”:
class HackedObjectInputStream extends ObjectInputStream {
public HackedObjectInputStream(InputStream in) throws IOException {
super(in);
}
@Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
if (resultClassDescriptor.getName().equals("oldpackage.Clazz"))
resultClassDescriptor = ObjectStreamClass.lookup(newpackage.Clazz.class);
return resultClassDescriptor;
}
}
后续问题 是否可以以向后兼容的方式将新类实例写入文件(显式设置类名)?目标是较旧的应用程序可以读取新应用程序写入的文件(包名称已更改)。
“类HackedObject 输出流如何扩展Object 输出 Stream”看起来如何?
public class HackedObjectOutputStream extends ObjectOutputStream {
public HackedObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
public final void writeObjectOverride(Object obj) throws IOException {
// How to change the package.class name ?
}
}
答案 0 :(得分:0)
使用readResolve()
和writeReplace()
方法。