字节码操作
介绍
java的动态性的两种常见方式
- 字节码操作
- 反射
运行时操作字节码可以实现的功能如下:
动态生成新的类
动态改变某个类的结构(添加/删除/修改 新的属性)
优势:
比反射开销小,性能高。
JAVAasist性能高于反射,低于ASM
常见的字节码操作类库
BCEL
Byte Code Engineering Library (BCEL) ,这是 Apache Software Foundation 的 Jakarta 项目的一部分。 BCEL 是 Java classworking 广泛 使用的一种 框架 , 它 可以让您深入 JVM 汇编语言进行类操作的细节。 BCEL 与 Javassist 有不同的处理字节码方法, BCEL 在实际的 JVM 指令层次上进行操作 (BCEL 拥有丰富的 JVM 指令级支持 ) 而 Javassist 所 强调 的是源代码 级别的 工作 。
ASM
是一个轻量级 java 字节码操作框架,直接涉及到 JVM 底层的操作和 指令
CGLIB
是一个强大的,高性能,高质量的 Code
Javaassist
性能较ASM差,跟cglib差不多,但是用用简单,很多框架都在使用
javassist
使用Javassist需要使用javassist.jar
优势:
比反射开销小,性能高。
JAVAsist性能高于反射,低于ASM
局限性:
JDK新语法不支持(包括泛型、枚举),不支持注解修改,但可以通过底层的javasist类来解决,具体参考:javassist.bytecode.annotaion
不支持数组的初始化,如 String[]{“1”,”2”},除非只有数组的容量为1
不支持内部类和匿名类
不支持 continue 和 break 表达式。
对于继承关系,有些不支持 。例如:- class A{} - class B extends A{} - class C enxends B {}
应用场景:
AOP:
给一个类增加新的方法
给一段语句前面和后面(before/after/around)动态的加代码
Reflection:起到类似反射的效果
javassist 的最外层的 API 和 JAVA 的反射包中的 API 颇为类似 。
它主要由 CtClass , CtMethod, ,以及 CtField 几个类组成。用以执行和 JDK 反射 API 中 java.lang.Class , java.lang.reflect.Method , java.lang.reflect.Method .Field 相同的 操作 。
方法操作
修改已有方法的方法体体(插入代码到已有方法体)
新增方法 删除方法
占位符参数介绍:
1 | import javassist.ClassPool; |