package java_216_字节码操作_javaassist库_介绍_动态创建新类_属性_方法_构造器_练习;
import javassist.ClassPool; import javassist.CtClass; import javassist.CtConstructor; import javassist.CtField; import javassist.CtMethod;
/**
测试使用JAVAasist生成一个新的类字节码操作:1.java动态性的两种常见实现方式:(框架里) 1)字节码操作 2)反射 2.运行时操作字节码可以让我们实现如下功能: 1)动态生成新的类 2)动态改变某个类的结构(添加/删除/修改 新的属性/方法) 3.优势: 1)比反射开销小 2)JAVAasist性能高于反射,低于ASM 4.常见的字节码操作类库 1)BCEL 2)ASM 上面两个效率最高但难学;因为他们基于底层的虚拟机操作 3)CGLIB(Code Generation Library) 是一个强大的,高性能,高质量的Code生成类库,基于ASM实现 4)Javassist 是一个开源的分析,编辑和创建java字节码的类库,性能较ASM差,跟CGLIB差不多,但是使用简单 1)Javassist的最外层的API和java的反射包中的API颇为类似 2)它主要由 CtClass(生成和操作类),CtMethod(生成和操作方法),以及CtField(生成和操作属性)几个类组成,用以执行和JDK反射API中java.lan.Class, java.lang.reflect.Method,java.lang.reflect.Field相同的操作 3)Javassist库的简单使用: a:通过程序创建一个全新的类,生成一个class文件;以前都是通过编辑器工具先写好一个类再进行编译 b.使用XJAD反编译工具;即通过XJAD反编译工具把class文件反编译成java文件*/ //注意 :用之前要下载javassist并导入架包;下载地址http://www.javassist.org/ public class Demo01 { public static void main(String[] args) throws Exception { //生成类池 ClassPool pool = ClassPool.getDefault(); //从类池获取 CtClass cc = pool.makeClass(“com.bjsxt.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("d:/myjava");//将上面构造器的类写入这个盘符里 //打印 System.out.println("新生成的类,成功写入!"); //在d:/myjava打开这个文件需要下载反编译软件XJad软件 }} //------------------------------- package java_216_字节码操作_javaassist库_介绍_动态创建新类_属性_方法_构造器_练习; /**
创建一个类 */ public class Emp {//Emp雇员 private int empno;//员工编号 private String ename;//员工姓名 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 Emp() { super(); } public Emp(int empno, String ename) { super(); this.empno = empno; this.ename = ename; } }
//结果---------------------------------- 双击XJad 打开文件