可能重复:
Java 类可以在运行时向自身添加方法吗?
是否可以在运行时为 Java 中的类合成新方法?有没有图书馆可以做到这一点?
进入一个已经加载的类?据我所知不是。
但是,您可能有兴趣生成一个新类。我看到两个选项:
像这样:
public static void printTest() {
System.out.println("Hey!");
}
然后查看字节码,看看 ConstantPool 中的“嘿!” 存储,然后获取该方法的字节码,将其缓存到一个字节数组中,然后使用预定义的字节 + 常量池(您之前检查过)动态创建一个方法,并使用您的字符串修改常量池。尽管对于更复杂的方法,这将变得非常棘手(注意:可以执行相同的操作来更改它调用的方法或获取的字段,例如更改为 err)
由于据我所知没有任何好的选择,所以这些是你最好的选择
除了字节码工程库,如果你的类有接口,你可以使用 Java 的Proxy
类。
带接口:
public interface Foo {
void bar();
}
具体类:
class FooImpl {
public void bar() {
System.out.println("foo bar");
}
}
要处理调用的方法,请使用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
}
}
然后使用以下方法创建一个FooFactory
来生成和包装FooImpl
实例Proxy
:
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 库不是本机的。(从 1.3 开始,一切都Proxy
在java.lang.reflect
。)