Java思考:如何在运行时重写或生成方法?

问题描述 投票:25回答:5

在普通的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()是static

,因为在执行“魔术”之后它是从其他类实例(它是Overrider)调用的,(因此我们阻止它访问本地字段)。

在纯Java中,有可能在运行时以编程方式重写类的方法(甚至创建新方法)?即使我在编译时不知道这些类,我也希望能够做到这一点。 ...

java reflection code-generation runtime
5个回答
10
投票

您可以使用cglib之类的代码即时生成代码>>


9
投票

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


8
投票

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

对于类,您将需要第三方库或编写大量代码。通常,以这种方式动态创建类是创建用于测试的模拟。


8
投票

我写了一篇article for java.net,内容涉及当类加载器使用Java代理加载类时如何透明地向类添加日志记录语句。

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


0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.