Java的:扩展类在运行时(Java: Extending Class At Runtime)

2019-06-23 11:05发布

我不得不延长在编译时一类的能力,但我需要能够创建使用已实例化的父类的实例在运行时,这个子类的实例。

这应该是在理论上是可行的,因为超类的构造函数是子类构造函数之前已经调用。

我没有访问程序足以实例化转变让我的子类,也没有中断原来的实例。

使用案例:有类X.我的代码在加载后的实例现有阵列。 我需要重写的情况下,X的一个方法之一与我的加载子类Ÿ延伸X.父程序只能通过数组访问的对象,所以我想用我的Ÿ实例来替换数​​组元素,但它需要表现为,如果它最初实例化到该数组。 我不能只封闭超实例和转移呼叫,并有与重新实例超难的并发症。

我希望这是更清晰。

Answer 1:

重申一下,你正在尝试做的..

在JVM中,存在ClassA的实例。 愿你动态修改ClassA的,的类heiarchy这样一个新的类存在一个称为ClassB的从ClassA的派生。 然后,你想ClassB的实例的实例,但有它的子类实现是ClassA的现有实例。 就像一个内存更换。

你可能想看看http://www.jboss.org/javassist 。 什么,你需要做的是更换的ClassLoader,然后确定何时加载ClassA的,然后实例化。 然后,您就需要构建ClassB的并返回来代替。

更新

一个进一步的研究之后还有你可以做你想做的可能性。 IDE的像Eclipse支持HotSwap'ing方法的实现,同时调试。 他们使用的仪表API。

http://zeroturnaround.com/blog/reloading_java_classes_401_hotswap_jrebel/

您可以替换方法体,但不能添加或删除方法本身。 所以,当你将不能够类型更改为新类型,可以完全替代你的新的实现方法实现。



Answer 2:

我会建议使用CGLIB :

CGLIB是一个功能强大,高性能和高质量代码生成库,它是用来扩展Java类和运行时实现接口

您可以在这里找到一些例子: https://github.com/cglib/cglib/wiki



Answer 3:

我不知道这是否是一个sollution但如果你有

public static Foo foo = new Foo();

你想与延伸美孚使酒吧的包装为美孚和使用反射来让富指向你的酒吧例如酒吧来取代它。

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);

}

至于说我不知道​​这是可能的,你的情况。



Answer 4:

你看着Java代理?

下面是从Javadoc中的一个片段:

“A动态代理类(简称为下面的代理类)是在创建类时,它实现在运行时指定的接口的列表的类”



文章来源: Java: Extending Class At Runtime