日志文章

2020-1-3 aflfte2011

javassist动态操作类的属性、方法、构造器、注解

package com.aflfte.test;

import java.lang.reflect.Method;
import java.util.Arrays;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Modifier;
import javassist.NotFoundException;

/**
 * 测试javaassist的API
 * 
 * @author jinhao
 *
 */
public class Demo02 {
//处理类的基本方法
public static void test01() throws Exception {
ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("com.aflfte.test.Emp");
byte[] bytes=cc.toBytecode();
System.out.println(Arrays.toString(bytes));
System.out.println(cc.getName());//获取 类名
System.out.println(cc.getSimpleName());//获取简要类名
System.out.println(cc.getSuperclass());//获取父类
System.out.println(cc.getInterfaces());//获取接口
}
//产生新的方法
public static void test02() throws Exception {
ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("com.aflfte.test.Emp");
/*//新建方法的方式一
CtMethod m=CtNewMethod.make("public int add(int a,int b){return a+b}", cc);
cc.addMethod(m);*/
//新建方法的方式二
CtMethod m2=new CtMethod(CtClass.intType,"add",new CtClass[] {CtClass.intType,CtClass.intType},cc);
m2.setModifiers(Modifier.PUBLIC);
m2.setBody("{System.out.println(\"方法体\")return $1+$2}");
cc.addMethod(m2);

//反射调用新生成的方法
Class cla=cc.toClass();
Object obj=cla.newInstance();
Method met=cla.getDeclaredMethod("add", int.class,int.class);
Object re=met.invoke(obj, 200,300);
System.out.println(re);

}
///修改已有的方法信息
public static void test03() throws Exception {
ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("com.aflfte.test.Emp");

CtMethod cm=cc.getDeclaredMethod("sayHello",new CtClass[] {CtClass.intType});
cm.insertBefore("System.out.println($1);System.out.println(\"start!!\")");//在方法体前面加入代码
cm.insertAfter("System.out.println(\"end!\")");//在方法体后面加入代码
cm.insertAt(11, "int b=3;System.out.println(\"b:\"+b);");//在指定行前插入代码

//反射调用新生成的方法
Class cla=cc.toClass();
Object obj=cla.newInstance();
Method met=cla.getDeclaredMethod("sayHello", int.class);
met.invoke(obj, 300);//执行方法

}
//操作属性信息
public static void test04() throws Exception {
ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("com.aflfte.test.Emp");
//新建属性
CtField f1=new CtField(CtClass.intType, "salary", cc);
f1.setModifiers(Modifier.PRIVATE);
cc.addField(f1,"1000");
//新加Salary的set和get方法
cc.addMethod(CtNewMethod.getter("getSalary", f1));
cc.addMethod(CtNewMethod.getter("setSalary", f1));

cc.getDeclaredField("ename");//获取指定属性

}
//操作构造器
public static void test05() throws Exception {
ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("com.aflfte.test.Emp");

CtConstructor[] cs=cc.getConstructors();
for(CtConstructor c:cs) {
System.out.println(c.getName());
}
}
//操作注解
public static void test06() throws Exception{
CtClass cc=ClassPool.getDefault().get("com.aflfte.test.Emp");
Object[] all=cc.getAnnotations();
Author a=(Author)all[0];
String name=a.name();
int year=a.year();
System.out.println("name:"+name+",year="+year);
}

public static void main(String[] args) throws Exception {
//test01();
//test02();
test06();
}
}

Emp类
package com.aflfte.test;
@Author(name="Chiba",year=2005)
public class Emp {
private int empno;
private String ename;
private int age;

public Emp() {
super();
}

public Emp(int empno, String ename, int age) {
super();
this.empno = empno;
this.ename = ename;
this.age = age;
}

public void sayHello(int a) {
System.out.println("say hello,"+a);
}

public int getEmpno() {
return empno;
}
public void setEmpno(int empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

}


注解类

package com.aflfte.test;

public @interface Author {
String name();
int year();
}


« 自定义类加载器 | 使用javassist动态生成一个新的类»