今日收获:
Javassist 学习
先写一下ssist的优点,因为class字节码文件是不可视化的,但是运用了javassist我们可以直接生成class文件并且可以很直观的看到并且,最重要的是我们可以直接修改class文件。
ClassPool pool = ClassPool.getDefault(); //是存储CtClass对象的容器,
//创建一个空类com.y4er.learn.Person
CtClass ctClass = pool.makeClass("src.main.java.com.cxk.ssit.Person");
//给ctclass类添加一个string类型的字段name
CtField name = new CtField(pool.get("java.lang.String"), "name", ctClass);
//设置private权限
name.setModifiers(Modifier.PRIVATE);
//初始化name字段为zhangsan
ctClass.addField(name,CtField.Initializer.constant("zhangsan"));
//生成get、set方法
ctClass.addMethod(CtNewMethod.getter("getName",name));
ctClass.addMethod(CtNewMethod.setter("setName",name));
//添加无参构造函数
CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass);
ctConstructor.setBody("{name=\"xiaocai\";}");
ctClass.addConstructor(ctConstructor);
//添加有参构造
CtConstructor ctConstructor1 = new CtConstructor(new CtClass[]{pool.get("java.lang.String")}, ctClass);
ctConstructor1.setBody("{$0.name=$1;}");
//$0代表this $1代表第一个传入的参数,默认自动含有$0
ctClass.addConstructor(ctConstructor1);
//创建一个public方法printName()无参无返回值
CtMethod printName = new CtMethod(CtClass.voidType, "printName", new CtClass[]{}, ctClass);
printName.setModifiers(Modifier.PUBLIC);
printName.setBody("{System.out.println($0.name);}");
ctClass.addMethod(printName);
ctClass.writeFile();// 写入.class文件
ctClass.detach();//从ClassPool中删除类
第一步:ClassPool.getDefault 声明一个存储CtClass对象的容器
第二步:pool.makeClass("Person") 创建一个名为Person的class文件,参数是Person路径
-
new CtField(pool.get("java.lang.String"), "name", ctClass) CtField添加变量
- sist中,无论用什么类都需要pool.get导入, 别的和反射区别不大
-
name.setModifiers(Modifier.PRIVATE); 设置name变量的类型为private,也可以是public.
-
ctClass.addField(name,CtField.Initializer.constant("zhangsan")); 初始化name的值
-
ctClass.addMethod(CtNewMethod.getter("getName",name)); 为name变量添加get方法
-
new CtConstructor(new CtClass[]{}, ctClass); 无参构造,如果是有参new CtClass[]{pool.get("java.lang.String")}
-
setBody("{name=\"xiaocai\";}"); body顾名思义身体,也就是往方法中添加东西,默认有this的标志,比如 this.name="xiaocai"
-
ctClass.addConstructor(ctConstructor1);
身体添加完后需要,添加到我们声明的类中
-
new CtMethod(CtClass.voidType, "printName", new CtClass[]{}, ctClass); 添加新的方法,void无参数, 方法名字
-
ctClass.writeFile();// 写入.class文件 最重要的一步
- 反射的关键是,ctfClass.toClass().newInstance() toClass() 函数直接将 CtClass 转换成 Class对象,不然没write写入是不能调用的,
Object o = ctClass.toClass().newInstance(); Method setName = o.getClass().getMethod("setName", String.class); Object y4er = setName.invoke(o, "Y4er"); Method printName1 = o.getClass().getMethod("printName"); printName1.invoke(o);
文章评论