[英]Java: Extending Class At Runtime
我有能力在编译时扩展 class,但我需要能够在运行时使用已经实例化的超类实例创建该子类的实例。
这在理论上应该是可能的,因为超类构造函数已经在子类构造函数之前被调用。
我没有足够的权限访问该程序,无法将实例化更改为我的子类,也无法中断原始实例化。
用例:有一个现有的class X的实例数组。我的代码是在之后加载的。 我需要用我加载的子类 Y 扩展 X 覆盖其中一个实例 X 的方法之一。父程序仅通过该数组访问对象,因此我想用我的 Y 实例替换该数组元素,但它需要表现得好像它最初被实例化到该数组中一样。 我不能只包含超类实例并转发调用,并且重新实例化超类时会遇到困难。
我希望这更清楚。
重申你正在尝试做的事情..
在 JVM 中,存在一个 ClassA 实例。 您想要动态修改 ClassA 的 class 层次结构,以便存在一个名为 ClassB 的新 class,它派生自 ClassA。 然后您想实例化 ClassB 的一个实例,但它的子类实现是 ClassA 的现有实例的子类实现。 类似于 memory 的替代品。
您可能需要查看http://www.jboss.org/javassist 。 您需要做的是替换 ClassLoader,然后确定何时加载 ClassA,然后实例化。 然后,您需要构造 ClassB 并将其返回。
更新
经过更多研究后,您仍然有可能做自己想做的事。 像 Eclipse 这样的 IDE 在调试时支持 HotSwap 方法实现。 他们使用仪器 API。
http://zeroturnaround.com/blog/reloading_java_classes_401_hotswap_jrebel/
您可以替换方法体,但不能添加或删除方法本身。 因此,虽然您无法将类型更改为新类型,但您可以用新实现完全替换方法实现。
我建议使用cglib :
cglib 是一个功能强大、高性能和高质量的代码生成库,它用于扩展 JAVA 个类并在运行时实现接口
你可以在这里找到一些例子: https://github.com/cglib/cglib/wiki
你看过 Java 代理吗?
这是来自 Javadoc 的片段:
“动态代理class(以下简称代理class)是一个class,它实现了创建class时在运行时指定的接口列表”
我不知道这是否是一个解决方案,但如果你有
public static Foo foo = new Foo();
并且您想用扩展 Foo 的 Bar 替换它,使 Bar 成为 Foo 的包装器,并使用反射让 foo 指向您的 Bar 实例。
public class Foo extends Bar {
private bar;
public Foo(Bar oldInstance) {
this.bar = oldInstance;
}
}
和
// exception handling ommitted
public static void onStartup() {
Class fooRefClass = FooRef.class;
Field fooRef = fooRefClass.getDeclaredField("foo");
Foo foo = (Foo)fooRef.get(null);
Bar bar = new Bar(foo);
fooRef.set(null, bar);
}
如前所述,我不知道您的情况是否可行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.