首先肯定是要先导入javassist.jar包
然后上代码
public class Demo01
{
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault(); //先获取一个ClasPool
CtClass cc = pool.makeClass("com.chengyu.annotation.Emp"); //创建一个类
CtField f = CtField.make("private int empno;",cc); //设置成员变量
CtField f1 = CtField.make("private String ename;",cc);
cc.addField(f); //将成员变量添加到类中
cc.addField(f1);
CtMethod m = CtMethod.make("public int getEmpno(){return empno;}",cc); //创建方法
CtMethod m1 = CtMethod.make("public void setEmpno(int empno){this.empno=$1;}",cc);
cc.addMethod(m1); //将方法添加到类中
cc.addMethod(m);
CtConstructor ctConstructor = new CtConstructor(new CtClass[]{CtClass.intType,pool.get("java.lang.String")},cc);//创建一个构造方法
ctConstructor.setModifiers(Modifier.PUBLIC); //设置构造方法为public的
ctConstructor.setBody("{this.empno=$1; this.ename=$2;}"); //设置构造方法体 这里的$1和$2对应参数位置
cc.addConstructor(ctConstructor); //将构造方法添加到类中
cc.writeFile("F:\\workspace\\idea_workspace\\iotest\\out\\production\\iotest"); //设置class文件写出的路径
Thread.sleep(100);
//下面是使用反射方法来测试class文件是否能够生成成功并且加载到JVM进行测试
URL [] urls = new URL[]{new URL
("file:/F:\\workspace\\idea_workspace\\iotest\\out\\production\\iotest\\com\\chengyu\\annotation\\Emp.class")};
URLClassLoader loader = new URLClassLoader(urls);
Class clazz = loader.loadClass("com.chengyu.annotation.Emp");
Field empno = clazz.getDeclaredField("empno");
Constructor c = clazz.getConstructor(int.class,String.class);
Object obj = c.newInstance(10,"String");
empno.setAccessible(true);
System.out.println(empno.get(obj));
}
}
然后看一下生成的字节码文件
package com.chengyu.annotation;
public class Emp {
private int empno;
private String ename;
public void setEmpno(int var1) {
this.empno = var1;
}
public int getEmpno() {
return this.empno;
}
public Emp(int var1, String var2) {
this.empno = var1;
this.ename = var2;
}
}
在设置构造方法的参数时一定要使用$来匹配,如果直接使用下面的代码
ctConstructor.setBody("{this.empno=empno; this.ename=ename;}");
则对应生成的字节码文件为
package com.chengyu.annotation;
public class Emp {
private int empno;
private String ename;
public void setEmpno(int var1) {
this.empno = var1;
}
public int getEmpno() {
return this.empno;
}
public Emp(int var1, String var2) {
this.empno = this.empno;
this.ename = this.ename;
}
}
所以在生成对应的构造函数时切记使用$来适配,当然在设置方法的参数时也建议使用$来适配
最后来看一下执行结果吧