javassist 常用方法整理
2018-02-25 17:51
218 查看
javassist简介
一个比较好的例子:http://yucaifu1989.iteye.com/blog/1850500
比较好的文档:http://blog.csdn.net/u011425751/article/details/51917895
Javassist是一个开源的java字节码操作工具,主要是对已经编译好的class文件进行修改和处理,这里我写了一个简单的说明,复杂的请去看www.javassist.com的官方文档。
亲测实例
1、首先去官网下载jar http://jboss-javassist.github.io/javassist/ 里面有例子。
2、同样的使用使用jd-gui打开要修改的jar,找到要修改的类名、方法名。
3、在2的基础上开始写修改代码
4、查看新生成的文件,将生成的新class文件替换jar包以前的class即可使用了。
这块有意思,编译器将true生成了1!=0了…..
在指定位置添加代码
// 在这个方法的182行添加关闭文件流的方法
method.insertAt(182, “fin.close();”);
指定生成新class位置
ctClass.writeFile(“path”);
加入try cath块
addCatch()
addCatch() 指的是在方法中加入try catch 块,需要注意的是,必须在插入的代码中,加入return 值$e代表 异常值。比如:
重写方法体
//获取要修改的具体方法
CtMethod cm=cc.getDeclaredMethod(“checkHardware”);
cm.setBody(“System.out.println(\”\”);”);
cm.setBody();方法可以重新设置方法体的内容。
cm.setName();重新设置方法名字。
使用方法中的参数
Javassist也提供了一些特殊的变量来代表方法参 数:1,1,2,$args…要注意的是,插入的source文本中不能引用方法本地变量的声明,但是可以允许声明一个新的方法本地变量,除非在程序 编译时加入-g选项。
0代表的是this,0代表的是this,1代表方法参数的第一个参数、数,以此类推," role="presentation" style="position: relative;">2代表方法参数的第二个参数,以此类推,2代表方法参数的第二个参数,以此类推,N代表是方法参数的第N个。例如:
//实际方法
void move(int dx, int dy)
//javassist
CtMethod m = cc.getDeclaredMethod(“move”);
//打印dx,和dy
m.insertBefore(“{ System.out.println(1);System.out.println(1);System.out.println(2); }”);
注意:如果javassist改变了$1的值,那实际参数值也会改变。
args指的是方法所有参数的数组,类似Object[],如果参数中含有基本类型,则会转成其包装类型。需要注意的时候,args指的是方法所有参数的数组,类似Object[],如果参数中含有基本类型,则会转成其包装类型。需要注意的时候,args[0]对应的是1,而不是1,而不是0,0!=0!=args[0],$0=this。
使用类中定义的属性(字段)
0是代表this也就是对象自己,所以直接使用0是代表this也就是对象自己,所以直接使用0.字段 进行赋值或者使用即可。
例如字段名字叫 status 就可以写成 $0.status=1;
注意:目前可以确定用这种方式对字段进行赋值是没问题的,使用字段的方法还没有测试过。
使用类中定义的方法
与使用字段方法相似,$0.方法名
例如:方法名字叫 get() 就可以写成 $0.get();
修改构造方法
//获取构造方法集合,也可以指定获取指定参数的构造方法
CtClass cc=….;
CtConstructor[] ctc= cc.getConstructors();
//使用某个构造方法,与普通方法操作相同
ctc[0].insertAfter(“{return ;}”);
转载自http://blog.csdn.net/qq_24209665/article/details/75528386
一个比较好的例子:http://yucaifu1989.iteye.com/blog/1850500
比较好的文档:http://blog.csdn.net/u011425751/article/details/51917895
Javassist是一个开源的java字节码操作工具,主要是对已经编译好的class文件进行修改和处理,这里我写了一个简单的说明,复杂的请去看www.javassist.com的官方文档。
亲测实例
1、首先去官网下载jar http://jboss-javassist.github.io/javassist/ 里面有例子。
2、同样的使用使用jd-gui打开要修改的jar,找到要修改的类名、方法名。
3、在2的基础上开始写修改代码
package start; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; public class Test1 { public static void main(String[] args) throws Exception { //创建类池(就是jar包),用来加载类 ClassPool cp=ClassPool.getDefault(); //jar包所在位置,如果这句代码不写,下面引用的类就是项目中引用的类 cp.insertClassPath("e:/checkLicense-3-3.1.jar"); //获取要修改的具体类,注意是完整路径包括类名 CtClass cc=cp.get("com.primeton.licensemanager.checklicense.LicenseCheckManager"); //获取要修改的具体方法 CtMethod cm=cc.getDeclaredMethod("checkHardware"); //开始对方法进行修改,这里是往方法的最前面插入了一条语句 cm.insertBefore("if(true)return;"); //保存,执行后会在工程下生成一个新的class文件,刷新一下项目即可看到 cc.writeFile(); } }
4、查看新生成的文件,将生成的新class文件替换jar包以前的class即可使用了。
这块有意思,编译器将true生成了1!=0了…..
在指定位置添加代码
// 在这个方法的182行添加关闭文件流的方法
method.insertAt(182, “fin.close();”);
指定生成新class位置
ctClass.writeFile(“path”);
加入try cath块
addCatch()
addCatch() 指的是在方法中加入try catch 块,需要注意的是,必须在插入的代码中,加入return 值$e代表 异常值。比如:
CtMethod m = ...; CtClass etype = ClassPool.getDefault().get("java.io.IOException"); m.addCatch("{ System.out.println($e); throw $e; }", etype); 实际代码如下: try { the original method body } catch (java.io.IOException e) { System.out.println(e); throw e; }
重写方法体
//获取要修改的具体方法
CtMethod cm=cc.getDeclaredMethod(“checkHardware”);
cm.setBody(“System.out.println(\”\”);”);
cm.setBody();方法可以重新设置方法体的内容。
cm.setName();重新设置方法名字。
使用方法中的参数
Javassist也提供了一些特殊的变量来代表方法参 数:1,1,2,$args…要注意的是,插入的source文本中不能引用方法本地变量的声明,但是可以允许声明一个新的方法本地变量,除非在程序 编译时加入-g选项。
0代表的是this,0代表的是this,1代表方法参数的第一个参数、数,以此类推," role="presentation" style="position: relative;">2代表方法参数的第二个参数,以此类推,2代表方法参数的第二个参数,以此类推,N代表是方法参数的第N个。例如:
//实际方法
void move(int dx, int dy)
//javassist
CtMethod m = cc.getDeclaredMethod(“move”);
//打印dx,和dy
m.insertBefore(“{ System.out.println(1);System.out.println(1);System.out.println(2); }”);
注意:如果javassist改变了$1的值,那实际参数值也会改变。
args指的是方法所有参数的数组,类似Object[],如果参数中含有基本类型,则会转成其包装类型。需要注意的时候,args指的是方法所有参数的数组,类似Object[],如果参数中含有基本类型,则会转成其包装类型。需要注意的时候,args[0]对应的是1,而不是1,而不是0,0!=0!=args[0],$0=this。
使用类中定义的属性(字段)
0是代表this也就是对象自己,所以直接使用0是代表this也就是对象自己,所以直接使用0.字段 进行赋值或者使用即可。
例如字段名字叫 status 就可以写成 $0.status=1;
注意:目前可以确定用这种方式对字段进行赋值是没问题的,使用字段的方法还没有测试过。
使用类中定义的方法
与使用字段方法相似,$0.方法名
例如:方法名字叫 get() 就可以写成 $0.get();
修改构造方法
//获取构造方法集合,也可以指定获取指定参数的构造方法
CtClass cc=….;
CtConstructor[] ctc= cc.getConstructors();
//使用某个构造方法,与普通方法操作相同
ctc[0].insertAfter(“{return ;}”);
转载自http://blog.csdn.net/qq_24209665/article/details/75528386
相关文章推荐
- javassist 常用方法整理
- JS 中对日期处理常用方法整理
- python3基础之整数常用的方法整理
- 自己整理的一些开发时候常用的js方法封装
- Objective-c 中CGGeometry几何类常用方法简单整理
- 详细整理Java 从命令控制台输入数据读取输入流System.in的几种常用方法
- 常用小方法整理3
- Android 常用方法--代码片--整理
- 项目中常用js方法整理common.js
- Linux下dpkg命令常用方法整理
- 学习笔记三、pandas包中常用方法整理
- JS总结篇--JS中常用的Math方法整理
- 项目中常用的JS方法整理
- ios 开发,通讯录信息调用常用方法,这个比较全,不用再整理了;
- JavaScript常用方法整理
- python中math模块常用的方法整理
- JS截取字符串常用方法详细整理
- PHP新特性DateTime常用方法整理
- JS截取字符串常用方法详细整理
- ios 开发,通讯录信息调用常用方法,这个比较全,不用再整理了;