核心接口
ClassPool
CtClass对象池,用于保存CtClass对象.
ClassPool pool = ClassPool.getDefault();
CtClass
java类字节码操作接口,与java类一 一对应,可以通过CtClass动态的修改java类字节码,可以从ClassPool中获取CtClass,也可以通过ClassPool创建CtClass,所有需要操作的java类字节码必须生成CtClass保存在ClassPool中.
CtClass c1 = pool.get("Point");
CtClass c2 = pool.makeClass("Point");
c2.writeFile();//将类字节码输出到当前目录
c2.defrost();//After defrost() is called, the CtClass object can be modified again.
c2.detach();//从ClassPool中删除一个CtClass对象
示例代码
import javassist.*;
import java.lang.reflect.Method;
/**
* Created by guor on 2015/3/27.
*/
public class BytecodeExamples {
public static void main(String[] args) throws Exception {
// 创建类
ClassPool pool = ClassPool.getDefault();
CtClass cls = pool.makeClass("cn.ibm.com.TestClass");
// 添加私有成员name及其getter、setter方法
CtField param = new CtField(pool.get("java.lang.String"), "name", cls);
param.setModifiers(Modifier.PRIVATE);
cls.addMethod(CtNewMethod.setter("setName", param));
cls.addMethod(CtNewMethod.getter("getName", param));
cls.addField(param, CtField.Initializer.constant(""));
// 添加无参的构造体
CtConstructor cons = new CtConstructor(new CtClass[]{}, cls);
cons.setBody("{name = \"Brant\";}");
cls.addConstructor(cons);
// 添加有参的构造体
cons = new CtConstructor(new CtClass[]{pool.get("java.lang.String")}, cls);
cons.setBody("{$0.name = $1;}");
cls.addConstructor(cons);
// 打印创建类的类名
System.out.println(cls.toClass());
// 通过反射创建无参的实例,并调用getName方法
Object o = Class.forName("cn.ibm.com.TestClass").newInstance();
Method getter = o.getClass().getMethod("getName");
System.out.println(getter.invoke(o));
// 调用其setName方法
Method setter = o.getClass().getMethod("setName", new Class[]{String.class});
setter.invoke(o, "Adam");
System.out.println(getter.invoke(o));
// 通过反射创建有参的实例,并调用getName方法
o = Class.forName("cn.ibm.com.TestClass").getConstructor(String.class).newInstance("Liu Jian");
getter = o.getClass().getMethod("getName");
System.out.println(getter.invoke(o));
}
}