Java反射:如何在运行时覆盖或生成方法?

iva*_*off 25 java reflection code-generation runtime

在普通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);
Run Code Online (Sandbox Code Playgroud)

现在,这个调用......

altered.myMethod();
Run Code Online (Sandbox Code Playgroud)

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

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

oxb*_*kes 10

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


die*_*ega 9

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


Tom*_*ine 8

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

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

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


Tho*_*sen 8

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

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

slf4j项目提供精致版本.