System.out.println("A read operation on a field is encountered "); 当在非本地字段上执行读取操作时,我如何添加语句(例如,上面的语句)?此外,我还需要知道所读取字段的详细信息,并且这组细节应该对应于字段的唯一性。
示例(删除问题中的抽象):
public class Greet{
int knowncount;
public Greet()
{
System.out.println("Hello");
knowncount++;
}
public Greet(String language)
{
if(String.equals("ENGLISH")) {System.out.println("Hello"); knowncount++; }
else if(String.equals("SPANISH")) {System.out.println("Hola"); knowncount++;}
else System.out.println("Language not recognized");
}
public void showCount()
{
System.out.println("count : "+knowncount);
}
}用户类测试是:
class test{
public static void main(String[] args){
Greet g("SPANISH");
g.showCount();
}
}在上面的示例中,在使用javassist之后,我们的代码应该输出:
A read operation on a field is encountered
1发布于 2015-07-01 14:23:53
你可以通过使用ExprEditor来做你想做的事情。ExprEditor允许您编辑FieldAccess中所做的工作,要实现您的请求,您可以创建一个注入器,执行以下操作:
ClassPool classPool = ClassPool.getDefault();
CtClass greetCtClass = classPool.get(Greet.class.getName());
greetCtClass.instrument(new ExprEditor() {
@Override
public void edit(FieldAccess fieldAccess)
throws CannotCompileException {
if (fieldAccess.getFieldName().equals("knowncount")) {
fieldAccess
.replace(" { System.out.println(\"A read operation on a field is encountered \"); $_ = $proceed($$); } ");
}
}
});
greetCtClass
.writeFile("<ROOT DIRECTORY WHERE THE CLASSES ARE>");解释参数的最佳方法是使用一个示例,假设Greet类(恰好在greatPackage中)位于下面的路径/home/user/dev/proj1/build/greetPackage/Greet.class中。在这个场景中,根目录将是/home/user/dev/proj1/build/。
上述所有锅炉板的兴趣线如下:
{ System.out.println(\"A read operation on a field is encountered \"); $_ = $proceed($$); }
这里发生了什么事?
$_ = $proceed($$);。您可以在Javassi协助教程中找到有关这方面的更多信息(在该部分中搜索FieldAccess,因为它们没有直接的锚点,对不起!)但基本上这一行的意思是,字段访问的结果值是为字段访问调用的虚拟方法的值,换句话说,是字段的实际值。请记住,您必须在一个分离的JVM进程中使用注入器重写Greet类,只有在之后,您才能够使用类的注入行为,除非您在类加载方面做了一些技巧,以确保加载修改后的版本。我不会讨论这些话题,因为它超出了范围,但是如果你也需要帮助,请说出来。我很乐意帮你。
https://stackoverflow.com/questions/30930400
复制相似问题