在Java中运行时合成新方法?

可能重复:
Java类可以在运行时向自己添加方法吗?

是否可以在运行时为Java中的类合成新方法? 有没有图书馆可以做到这一点?

除了字节码工程库之外,如果您有类的接口,则可以使用Java的Proxy类。

有了界面:

 public interface Foo { void bar(); } 

具体课程:

 class FooImpl { public void bar() { System.out.println("foo bar"); } } 

要处理InvocationHandler的方法,请使用InvocationHandler

 class FooInvocationHandler implements InvocationHandler { private Foo foo; FooInvocationHandler(Foo foo) { this.foo = foo; } public Object invoke(Object proxy, Method method, Object[] args) throws Exception { if (method.getName().equals("bar")) System.out.println("foo me"); // return null if you don't want to invoke the method below } return method.invoke(foo, args); // Calls the original method } } 

然后使用Proxy创建一个FooFactory来生成和包装FooImpl实例:

 public class FooFactory { public static Foo createFoo(...) { Foo foo = new FooImpl(...); foo = Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[] { Foo.class }, new FooInvocationHandler(foo)); return foo; } } 

这将包装FooImpl对象,以便:

 Foo foo = FooFactory.createFoo(...); foo.bar(); 

打印:

 foo me foo bar 

这是BCEL库的替代方案,它可以做到这一点以及更多,包括从运行时信息生成类,但BCEL库不是本机的。 ( Proxy在1.3以来的所有内容中都在java.lang.reflect 。)

进入已装载的课程? 不是我的知识。

但是,您可能有兴趣生成一个新类。 我看到两个选择:

  • 我最近创建了一个项目,它根据包含代码的String生成一个类,并将其加载到系统中,然后运行它的main方法。 但是,这需要安装JDK =非常不可靠
  • 通过BCEL。 这也有坏处,但整体看起来似乎更好。 它要求您事先获得方法的字节码。 现在你可以做一些技巧,例如,制作一个方法

像这样:

 public static void printTest() { System.out.println("Hey!"); } 

然后看看字节码,看看ConstantPool中的哪个位置“嘿!” 存储,然后获取方法的字节码,将其缓存到字节数组中,然后动态创建一个带有预定义字节+常量池(您之前检查过)的方法,并使用您的字符串修改constantpool。 对于更复杂的方法,这会变得非常棘手(注意:可以更改它调用的方法,或者获取字段,例如更改为错误)

因为就我看来,没有任何好的选择,所以这些是你最好的选择