在普通的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);
现在,此调用...
而不是Overrider.myMethod()。altered.myMethod();
...将调用Injector.myMethod()
Injector.myMethod()是static
,因为在执行“魔术”之后它是从其他类实例(它是Overrider)调用的,(因此我们阻止它访问本地字段)。在纯Java中,有可能在运行时以编程方式重写类的方法(甚至创建新方法)?即使我在编译时不知道这些类,我也希望能够做到这一点。 ...
您可以使用cglib之类的代码即时生成代码>>
在java6中已添加了转换任何已加载类的可能性。看看java.lang.instrument包中的changes
对于接口,有java.lang.reflect.Proxy
。
对于类,您将需要第三方库或编写大量代码。通常,以这种方式动态创建类是创建用于测试的模拟。
我写了一篇article for java.net,内容涉及当类加载器使用Java代理加载类时如何透明地向类添加日志记录语句。
[它使用Javassist库来处理字节码,包括使用Javassist编译器生成额外的字节码,然后将其插入适当的位置,然后将所得的类提供给类加载器。
如果我做对了,与您有关的主要问题是如何通过实例接口方法传递静态方法委托(如C#)。
您可以查看本文:A Java Programmer Looks at C# Delegates (archived),它向您展示如何获取对静态方法的引用并调用它。然后,您可以创建一个包装器类,该包装器类在其构造函数中接受静态方法名称,并实现您的基类以从实例方法中调用静态方法。