`

利用javaassist修改Class文件

    博客分类:
  • j2se
 
阅读更多

我们在开发中有时候会遇到这样的问题,就是使用的某个第三方包中的某些类或者某些方法不能满足我们的需求,但我们又没有源代码可以改,如果通过反编译的话又容易出错,javaassist这个第三方包就可以解决这个问题,这个第三方包支持对字节码的直接编辑,说得直白点,就是可以用这个第方包通过编程实现对Class类的直接修改。我也是刚用这个,所以写一点目前我知道的方法。
javaasist.jar这个包在网上可以方便下到,他里面主要有这么几个类
ClassPool:Class载入器
CtClass:可供修改的Class
CtMethod:可供修改的方法
CtField:可供修改的域
用法是通过ClassPool载入一个你要修改的类(载入成CtClass),那么你就可以用CtClass的方法去获取这个类的所有方法和域,并相应解析成CtMethod或者CtField,然后再修改。
举个例子,比如我有一个a.class,里面有一个方法叫public void b(int a){System.out.println(a);)
如果我想把这个方法改成public void b(int a){System.out.println(a+1);}
那么用如下代码

ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("a");
CtMethod m = cc.getDeclaredMethod("b");
上边的代码是将a.class载入到了cc,并将里面的b方法载入到了m,然后再进行修改,对方法的修改,CtMethod类提供了setBody(直接写入内容体),insertAfter(在后面补充),insertBefore(在前面补充)这些方法,下边是示例
m.setBody("{System.out.println(a+1);}");
这里要注意,写入的实际程序体需要用{}给包起来,如果没有会编译出错,但上边这样的写法编译还是会出错的,为什么呢,因为方法的参数不能够直接写在body里,而要用引用的方式,对CtMethod,提供了这样的引用方式,$1,$2....分别对应相应的参数,所以上边的代码要改成
m.setBody("{System.out.println($1+1);}");
这样就对了
这样我们就已经把这个方法改掉了,接下来要生成修改过后的Class文件,
cc.writeFile();
这样新的Class文件就生成了
那么实际的操作是怎么样的呢,我们应该先新建一个Java项目,然后把你要修改的Class所在的包以及javaassisst.jar都导入进去,然后写代码修改,最后生成的新class文件就会放置在你新建的这个项目下,然后你把这个修改过的class文件替换以前的就OK了。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics