BCEL 可以深入 JVM 汇编语言进行类操作的细节。 BCEL 与 javassist 有不同的处理字节码方法, BCEL 在实际的 JVM 指令层次上进行操作,而 javassist 所强调的是源代码级别的工作。
ASM
是轻量级 java 字节码操作框架,直接涉及到 JVM 底层的操作和指令。 高性能,高质量
CGLB
基于 ASM 实现
javassist
性能低于 ASM 跟 CGLB 差不多,但是使用简单,很多开源框架都使用的是 javassist 。 javassist 比反射开销小,性能高。
小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:664389243 这是小编创建的java高阶学习交流群,加群一起交流学习深造。群里也有小编整理的2019年最新最全的java高阶学习资料!
javassist 的最外层的 API 和 JAVA 的反射包中的 API 颇为相似。它主要由 CtClass、 CtMethod 以及 CtField 几个类组成,用以执行和 JDK 反射 API 中 java.lang.Class、 java.lang.reflect.Method 、 java.lang.reflect.Field 相同的操作。
局限性
JDK5.0 新语法不支持(包括泛型、枚举),不支持注解修改
不支持数组的初始化
不支持内部类和匿名类
不支持 continue 和 break 表达式
对于继承关系,有些不支持。
maven : mvnrepository.com/artifact/ja…
反射调用方法
publicclassUser {privateString name;privateInteger age;publicvoidsum(inta,intb){intsum = a + b; System.out.println("sum = "+ sum); }publicstaticvoidmain(String[] args) {try{Class clz =Class.forName("javassist.User"); Object newInstance = clz.newInstance(); Method method = clz.getDeclaredMethod("sum",int.class,int.class); Object invoke = method.invoke(newInstance,1,3); }catch(Exception e){ } }}复制代码
javassist 生成 class 文件
//使用javassist创建class文件ClassPool pool = ClassPool.getDefault();//创建 class 文件CtClass userClass = pool.makeClass("com.beisiji.javassist.User");//创建 id 属性CtField idField = CtField.make("private Integer id;", userClass);//创建 name 属性CtField nameField = CtField.make("private String name;", userClass);//添加属性userClass.addField(idField); userClass.addField(nameField);//创建方法CtMethod setIdMethod = CtMethod.make("public void setId(Integer id) { this.id = id; }", userClass); CtMethod getIdMethod = CtMethod.make("public Integer getId() { return id; }", userClass);//添加方法userClass.addMethod(setIdMethod); userClass.addMethod(getIdMethod);//创建构造器CtConstructor ctConstructor =newCtConstructor(newCtClass[]{CtClass.intType, pool.get("java.lang.String")}, userClass);ctConstructor.setBody("{ this.id = id;this.name = name; }");userClass.addConstructor(ctConstructor);userClass.writeFile("C:/Users/yuanl/Desktop/md_dir");复制代码
javassist 修改类文件信息
//使用javassist修改类文件信息(添加方法)ClassPool pool = ClassPool.getDefault();//需要加载的类信息(需要修改类信息的全限定名称)CtClass userClass = pool.get("executor.ExecutorDemo");//创建方法CtMethod method =newCtMethod(CtClass.intType,"add",newCtClass[]{CtClass.intType, CtClass.intType}, userClass);//设置方法权限method.setModifiers(Modifier.PUBLIC); method.setBody("{return $1 + $2;}");//$0:this , $1第一个参数 , $2第二个参数userClass.addMethod(method); userClass.writeFile("C:/Users/yuanl/Desktop/md_dir");//调用添加的方法Class clz = userClass.toClass();ObjectnewInstance = clz.newInstance(); Method addMethod = clz.getDeclaredMethod("add",int.class,int.class);Objectinvoke = addMethod.invoke(newInstance,2,3); System.out.println("invoke = "+ invoke);复制代码
小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:664389243 这是小编创建的java高阶学习交流群,加群一起交流学习深造。群里也有小编整理的2019年最新最全的java高阶学习资料!
网友评论