Javareflection:如何在运行时覆盖或生成方法?

在普通Java中,可以在运行时以编程方式覆盖类的方法(甚至创建新方法)?

即使我在编译时不了解类,我希望能够这样做。

我在运行时重写的意思是:

abstract class MyClass{ public void myMethod(); } class Overrider extends MyClass{ @Override public void myMethod(){} } class Injector{ public static void myMethod(){ // STATIC !!! // do actual stuff } } // some magic code goes here Overrider altered = doMagic( MyClass.class, Overrider.class, Injector.class); 

现在,这个调用……

 altered.myMethod(); 

…将调用Injector.myMethod()而不是Overrider.myMethod()

Injector.myMethod()是静态的 ,因为在执行“magic”之后,它会从不同的类实例(它是Overrider)调用,(因此我们阻止它访问本地字段)。

你可以使用像cglib这样的东西来实时生成代码

在java6中添加了转换任何已经加载的类的可能性。 看一下java.lang.instrument包中的更改

对于接口,有java.lang.reflect.Proxy

对于课程,您需要第三方库或编写相当多的代码。 通常以这种方式动态创建类是为了测试创建模拟。

还有一个允许修改类的instrumentation API。 您还可以使用自定义类加载器或磁盘上的类文件来修改类。

我为java.net撰写了一篇文章,介绍如何在类加载器使用java代理加载日志语句时将其透明地添加到类中。

它使用Javassist库来操作字节代码,包括使用Javassist编译器生成额外的字节码,然后将其插入适当的位置,然后将生成的类提供给类加载器。

slf4j项目提供精炼版本。

如果我做对了,关注的主要问题是如何通过实例接口方法传递静态方法委托(如在C#中)。

您可以查看这篇文章: Java程序员查看C#Delegates ,它向您展示如何获取对静态方法的引用并调用它。 然后,您可以创建一个包装器类,该类在其构造函数中接受静态方法名称,并实现您的基类以从实例方法调用静态方法。