如何将对象序列化,如果它被移动到另一个包或重命名,保持向后兼容性?

时间:2016-01-01 23:56:19

标签: java serialization

考虑以下情况,问题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 ?
    }
}

1 个答案:

答案 0 :(得分:0)

使用readResolve()writeReplace()方法。