0 Java字节码操作简介:
1 JAVAssist简介:
2 JAVAssist好处在于 在源码级别可以定义,不需要学习JVM指令
代码:
import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; import javassist.CtConstructor; import javassist.CtField; import javassist.CtMethod; /** * 可以使用XJad来打开class文件 * 测试使用javassist生成一个新的类 class文件 * 需要下载 javassist jar包 * @author * */ public class Demo01 { public static void main(String[] args) throws Exception { ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.makeClass("com.bean.Emp"); //创建属性 CtField f1 = CtField.make("private int empno;", cc); CtField f2 = CtField.make("private String ename;", cc); cc.addField(f1); cc.addField(f2); //创建方法 CtMethod m1 = CtMethod.make("public int getEmpno(){return empno;}", cc); CtMethod m2 = CtMethod.make("public void setEmpno(int empno){this.empno=empno;}", cc); cc.addMethod(m1); cc.addMethod(m2); //添加构造器 CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType,pool.get("java.lang.String")}, cc); constructor.setBody("{this.empno=empno; this.ename=ename;}"); cc.addConstructor(constructor); cc.writeFile("c:/myjava"); //将上面构造好的类写入到c:/myjava中 最后生成字节码 System.out.println("生成类,成功!"); } }
API代码操作:
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; /** * 测试javassist的API * @author 尚学堂高淇 www.sxt.cn * */ public class Demo02 { /** * 处理类的基本用法 * @throws Exception */ public static void test01() throws Exception{ ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get("com.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()); //获得接口 } /** * 测试产生新的方法 * @throws Exception */ public static void test02() throws Exception{ ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get("com.test.Emp"); // CtMethod m = CtNewMethod.make("public int add(int a,int b){return a+b;}", cc); CtMethod m = new CtMethod(CtClass.intType,"add", new CtClass[]{CtClass.intType,CtClass.intType},cc); m.setModifiers(Modifier.PUBLIC); m.setBody("{System.out.println(\"www.sxt.cn\");return $1+$2;}"); cc.addMethod(m); //通过反射调用新生成的方法 Class clazz = cc.toClass(); Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象 Method method = clazz.getDeclaredMethod("add", int.class,int.class); Object result = method.invoke(obj, 200,300); System.out.println(result); } /** * 修改已有的方法的信息,修改方法体的内容 * @throws Exception */ public static void test03() throws Exception{ ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get("com.test.Emp"); CtMethod cm = cc.getDeclaredMethod("sayHello",new CtClass[]{CtClass.intType}); cm.insertBefore("System.out.println($1);System.out.println(\"start!!!\");"); // AOP 前置通知 cm.insertAt(9, "int b=3;System.out.println(\"b=\"+b);"); cm.insertAfter("System.out.println(\"end!!!\");"); // AOP 后置通知 //通过反射调用新生成的方法 Class clazz = cc.toClass(); Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象 Method method = clazz.getDeclaredMethod("sayHello", int.class); method.invoke(obj, 300); } /** * 属性的操作 * @throws Exception */ public static void test04() throws Exception{ ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get("com.test.Emp"); // CtField f1 = CtField.make("private int empno;", cc); CtField f1 = new CtField(CtClass.intType,"salary",cc); f1.setModifiers(Modifier.PRIVATE); cc.addField(f1); // cc.getDeclaredField("ename"); //获取指定的属性 //增加相应的set和get方法 cc.addMethod(CtNewMethod.getter("getSalary", f1));; cc.addMethod(CtNewMethod.getter("setSalary", f1));; } /** * 构造方法的操作 * @throws Exception */ public static void test05() throws Exception { ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get("com.test.Emp"); CtConstructor[] cs = cc.getConstructors(); for (CtConstructor c : cs) { System.out.println(c.getLongName()); } } public static void test06() throws Exception{ CtClass cc = ClassPool.getDefault().get("com.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 { test06(); } }