在运行时替换字段的类(用于protostuff)

时间:2015-02-24 13:57:45

标签: java reflection classloader protostuff

我正在研究一个类的不同版本之间向后兼容的框架(来自序列化的二进制表示)。

我坚持的一件事是如何在运行时用不同版本的字段类替换类中使用的字段。

如果有问题的类是父对象(Java - how to load different versions of the same class?),我知道如何使用类加载器来完成它。

但是,当我已经拥有一个物体并且需要改变它的一个区域时(或者我不知道如何),这不起作用。反射API似乎也没有在实例化后设置类的方法。

我举一个例子,以便更好地理解。让我们说我有一个包装类:

class Wrapper{
  int version;
  Object content;
}

现在假设我作为变量内容加载的类I在20个版本之前发生了变化。我仍然使用当时使用的原始.java(或.class-)文件。我打算做的是,使用旧的类内容版本创建一个包装器实例,从光盘加载,转换它并将其写入包含用于内容的类的当前版本的最新版本的包装器。

它也需要非常通用,这就是为什么我使用对象而不是包装器中的实际类。真正的问题是我需要这个用于protostuff运行时(de-)序列化。这意味着我将Wrapper.class传递给protostuff,并为它生成序列化模式。这当前失败了,因为wrapper.class文件自动引用新版本(它在项目包中)。

Schema<Wrapper> schema= RuntimeSchema.getSchema(Wrapper.class);
Wrapper resultWrapper = schema.newMessage();

我不确定这是否经历过类加载器,如果是这样,何时。我想它必须,但我不确定这是什么时候发生的。

接近这个的最佳方式是什么?

1 个答案:

答案 0 :(得分:1)

您可以做的一件事是为不同版本分别设置ClassLoader个对象。由于ClassLoader是类的标识的一部分,除了它的包和名称之外,您还可以在内存中拥有该类的多个版本。这种方法的唯一问题是你最终会依赖反射来对这些对象做任何事情。

然后,您可以创建当前版本的对象,并使用反射传输这些字段的值。这将解决在运行时必须修改字段类型的问题。