1. ClassFile
我们都知道, 在.class 文件中, 存储的是 ByteCode 数据. 但是, 这些 ByteCode 数据并不是杂乱无章的, 而是遵循一定的数据结构
这个.class 文件遵循的数据结构就是由 Java Virtual Machine Specification 中定义的 The class File Format: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
2. 字节码类库
ASM 是操作字节码的类库, 但并不是唯一的, 还有许多其它的操作字节码的类库
2.1 常见的字节码类库
在下面列举了几个比较常见的字节码类库
- Apache Commons BCEL: 其中 BCEL 为 Byte Code Engineering Library 首字母的缩写
- Javassist: Javassist 表示 Java programming assistant
- ObjectWeb ASM: 本课程的研究对象
- Byte Buddy: 在 ASM 基础上实现的一个类库
那么, 字节码的类库和 ClassFile 之间是什么样的关系呢?我们可以用下图来表示
对于上图, 我们用三句来描述它们的关系
- 中间层-多个.class 文件, 虽然每个类里面的内容各不相同, 但它们里面的内容都称为字节码 (ByteCode)
- 中下层-不论这些.class 文件内容有怎样大的差异, 它们都共同遵守同一个数据结构, 即 ClassFile
- 中上层-为了方便于人们对于字节码 (ByteCode) 内容的操作, 逐渐衍生出了各种操作字节码的类库
- 上下层-不考虑中间层, 我们可以说, 不同的字节码类库是在同一个 ClassFile 结构上发展起来的
既然有多个可以选择的字节码类库, 那么我们为什么要选择 ASM 呢?这就得看 ASM 自身所有的特点, 或者说与众不同的地方了
2.2 ASM 的特点
与其它的操作 Java 字节码的类库相比, ASM 有哪些与众不同的地方呢?
在实现相同的功能前提下, 使用 ASM, 运行速度更快 (运行时间短, 属于"时间维度"), 占用的内存空间更小 (内存空间, 属于"空间维度"). 简而言之, ASM 的特点就是 fast 和 small
3. ASM 与 ClassFile 的关系
为了大家更直观的理解 ASM 与 ClassFile 之间关系, 我们用下图来表示. 其中, Java ClassFile 相当于"树根"部分, ObjectWeb ASM 相当于"树干"部分, 而 ASM 的各种应用场景属于"树枝"或"树叶"部分
学习 ASM 有三个不同的层次
- 第一个层次, ASM 的应用层面. 也就是说, 我们可以使用 ASM 来做什么呢?对于一个.class 文件来说, 我们可以使用 ASM 进行 analysis, generation 和 transformation 操作.
- 第二个层次, ASM 的源码层面. 也就是, ASM 的代码组织形式, 它为分 Core API 和 Tree API 的内容
- 第三个层次, Java ClassFile 层面. 从 JVM 规范的角度, 来理解.class 文件的结构, 来理解 ASM 中方法和参数的含义