BCEL
可以深入 JVM
汇编语言进行类操作的细节。 BCEL
与 javassist
有不同的处理字节码方法, BCEL
在实际的 JVM
指令层次上进行操作,而 javassist
所强调的是源代码级别的工作。
是轻量级 java
字节码操作框架,直接涉及到 JVM
底层的操作和指令。 高性能,高质量
基于 ASM
实现
性能低于 ASM
跟 CGLB
差不多,但是使用简单,很多开源框架都使用的是 javassist
。 javassist
比反射开销小,性能高。
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…
反射调用方法
public class User { private String name; private Integer age; public void sum(int a,int b){ int sum = a + b; System.out.println("sum = " + sum); } public static void main(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 = new CtConstructor(new CtClass[]{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 = new CtMethod(CtClass.intType, "add", new CtClass[]{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(); Object newInstance = clz.newInstance(); Method addMethod = clz.getDeclaredMethod("add", int.class, int.class); Object invoke = addMethod.invoke(newInstance, 2, 3); System.out.println("invoke = " + invoke); 复制代码