java动态性的两种常见的实现方式:
①字节码操作
②反射
运行时操作字节码可以让我们实现如下功能:
①动态生成新的类
②动态改变某个类的结构(添加、删除、修改 新的属性或方法)
优点:
比反射的开销小,性能高
Javassist性能高于反射,低于ASM
BCEL(Byte Code Engineering Library):
是java classworking 广泛使用的一种框架,它可以让你深入JVM汇编语言进行类操作的细节。BCEL与Javassist有不同的处理字节码的方法,BCEL在实际的JVM指令层次上进行操作(BCEL拥有丰富的JVM指令级支持)而javassist所强调的是源代码级别的工作。
ASM:
是一个轻量级java字节码操作框架,直接涉及到JVM底层的操作和指令。
CGLIB(Code Generation Library):
是一个强大的,高性能,高质量的code生成类库,基于ASM实现。
javassist:
是一个开源的分析、编辑和创建java字节码的类库。性能比ASM差,与cglib差不多,但是使用简单,很多开源框架都在使用。
导入javassist.jar包:
1 /** 2 * 3 * 测试使用javassist生成一个新的类 4 * 5 * @author Zhang XiaoDao 6 * 7 */ 8 public class Demo01 { 9 public static void main(String[] args) throws Exception { 10 //获取默认的类池 11 ClassPool pool = ClassPool.getDefault(); 12 //需要创建的类 13 CtClass cc = pool.makeClass("com.zzp.bean.Emp"); 14 15 //创建属性,也可以给属性赋值 16 CtField f1 = CtField.make("private int empno", cc); 17 CtField f2 = CtField.make("private String ename", cc); 18 cc.addField(f1); 19 cc.addField(f2); 20 21 //创建相关的方法 22 //创建set/get方法 23 CtMethod.make("public int getEmpno(){return empno;}", cc); 24 CtMethod.make("public void setEmpno(int empno){this.empno = empno;}", cc); 25 26 CtMethod m1 = CtMethod.make("public String getEname(){return ename;}", cc); 27 CtMethod m2 = CtMethod.make("public void setEname(String ename){this.ename = ename;}", cc); 28 cc.addMethod(m1); 29 cc.addMethod(m2); 30 31 //添加构造器 32 CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType,pool.get("java.lang.String") 33 },cc); 34 //设置构造器的方法体,method也能设置方法体 35 constructor.setBody("{this.empno=empno; this.ename=ename;}"); 36 cc.addConstructor(constructor); 37 38 //将上面写好的类生成到桌面 39 cc.writeFile("c:/desktop"); 40 System.out.println("生成类成功"); 41 } 42 }
原文地址:https://www.cnblogs.com/zhangzhipeng001/p/9127762.html
时间: 2024-10-09 01:06:38