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

标签 java reflection classloader protostuff

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

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

如果所讨论的类是父对象 (Java - how to load different versions of the same class?),我知道如何使用类加载器来实现。

但是当我已经有了一个对象并且需要更改它的一个字段时(或者我不知道如何更改),这就不起作用了。反射 API 似乎也没有在实例化后设置类的方法。

我举个例子,这样更好理解。假设我有一个包装器类:

class Wrapper{
  int version;
  Object content;
}

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

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

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

我不确定这是否会通过类加载器,如果是,什么时候。我想它必须,但我不确定什么时候会发生。

解决这个问题的最佳方法是什么?

最佳答案

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

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

关于java - 在运行时替换字段的类(用于 protostuff),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28697703/

相关文章:

java - 如何从另一个 jar 文件调用一个类?

java - 接口(interface) > 抽象类 > 具体类模式

java - 我的第一次登录尝试没有给我任何消息

Java:如何覆盖这个泛型方法?

java - 广播组崩溃

c# - 查找方法的实例

c# - 如何使用反射访问私有(private)基类字段

Java反射: Creating class instance dynamically and assigning it to Parent object

java - 使用 JDO 持久化/检索对象时 DataNucleus DAO 对象中的 ClassCastException

programming-languages - 哪些框架(和相关语言)支持类替换?