我坚持使用javassist.我在运行时向我的对象类添加了一个新方法。
我的object类:
package tmp3;
public class Car {
public Car(){}
}我的测试类:
package tmp3;
import java.lang.reflect.Method;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
public class TestMain {
public static void main(String[] args) {
try {
CtClass ctclass = ClassPool.getDefault().get("tmp3.Car");
CtMethod newmethod = CtNewMethod.make("public void testPrint() { System.out.println(\"test ok\"); }",ctclass);
ctclass.addMethod(newmethod);
ctclass.writeFile();
for(Method me: ctclass.toClass().getDeclaredMethods()){ //test print, ok
System.out.println(me.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}但在那之后,我不知道如何调用它。我读到过javassist没有调用方法的能力。那么,我如何才能调用我刚才用javassist添加的方法呢?
我在两天内尝试了很多东西,但都没有成功。你能帮我弄一下这个吗?
发布于 2012-12-10 17:51:56
Java类具有静态接口,这意味着,正如您可能已经知道的那样,默认情况下,Java不是为在运行时向类添加方法而设计的,所以它有点棘手,但实现您想要的并不难。
您已经使用了Javassist (一个字节码修改器框架)来设计您的已编译类,以添加更多表示新方法的字节码。您可以选择以下两种场景之一:
场景1:在注入之前与您的汽车类一起编译的代码
在这种情况下,当您的代码正在编译时,Java Compiler只知道Car接口,而没有任何注入。所以你不能直接调用注入的方法,就像这样:
Car car = new Car();
car.testPrint();你必须像@Scorpion正确评论的那样,通过反射来做到这一点:
Car car = new Car();
Method method = car.getClass().getMethod("testPrint", new Class[]{});
method.invoke(car,new Object[]{});但这并不是唯一的方法。
场景2:使用编译和注入的类的代码
如果编译Car类,注入它,然后对编译的类进行编写代码(例如,将Car类放在jar文件中),您将能够像调用任何其他常规方法一样调用注入的方法。
执行以下练习:
Car类Car实例的新项目中的一个类,请注意,您现在可以轻松地调用testPrint方法了。<代码>G222
有几件事你应该注意:
java.lang.ClassFormatError,并显示一条错误消息,告诉你有一个截断的类文件。如果Javassist没有将所有的字节码加载到内存中,并试图对同一个类文件进行读写操作,就会发生这种情况,这会导致整个系统的混乱。要避免这种情况,您可以在写入文件之前写入其他路径或确保已将所有字节码加载到内存中(使用CtClass中的toByteCode() )。发布于 2015-08-11 05:53:08
使用java反射来调用它,javassist用于类的修改和加载……然后使用java反射来运行它(调用...)。
https://stackoverflow.com/questions/13797919
复制相似问题