【发布时间】:2017-04-11 02:45:37
【问题描述】:
我必须在运行时修改以下类以在每个方法的末尾打印实例变量“count”的值。
package test.hib.javaassist;
import java.io.IOException;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
public class JavaAssistTest {
int count;
public void doSomething1(){
count++;
}
public void doSomething2(){
count++;
}
public void doSomething3(){
count++;
}
public void doSomething4(){
count++;
}
}
以下是主类,我试图在 javaassist 的帮助下更改字节码。
package test.hib.javaassist;
import java.io.IOException;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
public class Main {
public static void main(String[] args) throws NotFoundException, CannotCompileException, IOException {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("test.hib.javaassist.JavaAssistTest");
CtMethod[] methods = cc.getDeclaredMethods();
for(CtMethod method : methods){
if(! (method.getName().equals("main"))){
method.insertAfter("{System.out.println(count);}");
//method.insertAfter("System.out.println($type);");
}
}
cc.writeFile();
System.out.println("Completed editting");
JavaAssistTest test = new JavaAssistTest();
test.doSomething1();
test.doSomething2();
test.doSomething3();
test.doSomething4();
System.out.println("Finished");
}
}
目前正在打印中
Completed editting
Finished
我希望它打印出来
Completed editting
1
2
3
4
Finished
你能指出我的代码中的错误吗?
【问题讨论】:
-
我想(只是猜测)该类已经加载,因此对 .class 文件的更改不会反映在当前 JVM 的运行时中。您可以尝试按照描述重新加载类,例如这里:stackoverflow.com/a/3971771/281108
-
嗯....看起来有点复杂。我尝试了另一种加载课程的方式。类 testClass = Loader.getSystemClassLoader().loadClass("test.hib.javaassist.JavaAssistTest"); JavaAssistTest 测试 = (JavaAssistTest)testClass.newInstance();但结果没有变化!!
-
我很确定如果已经加载了类,它不会重新加载它。
-
加载器文档说“与常规类加载器不同,这个类加载器从 ClassPool 获取字节码。”