ASM核心API简介(2)
发表于2019-08-02,长度2071,
182个单词,
5分钟读完
ASM 中生成和转换字节码的API主要是基于抽象类 ClassVisitor 的。这里讲一下 ClassVisitor 的用法。
有很多平台都提供了这个类,甚至包括Java自己。注意ASM的包名是org.objectweb.asm
方法定义
ClassVisitor 的方法如下:
public abstract class ClassVisitor {
public ClassVisitor(int api);
public ClassVisitor(int api, ClassVisitor cv);
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces);
public void visitSource(String source, String debug);
public void visitOuterClass(String owner, String name, String desc);
AnnotationVisitor visitAnnotation(String desc, boolean visible);
public void visitAttribute(Attribute attr);
public void visitInnerClass(String name, String outerName, String innerName, int access);
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value);
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions);
void visitEnd();
}
每个方法都对于类文件中的一块结构(连名字也一样),这也是它为啥叫元素模型的原因。 简单的块通过没有返回值的方法访问,参数就是这一块的内容。比较复杂的块通过返回备用类的方法访问,分别是visitAnnotation返回AnnotationVisitor, visitField返回 FieldVisitor,visitMethod返回MethodVisitor。这些返回类型会递归使用这样的规则,比如FieldVisitor也包含类似的方法:
public abstract class FieldVisitor {
public FieldVisitor(int api);
public FieldVisitor(int api, FieldVisitor fv);
public AnnotationVisitor visitAnnotation(String desc, boolean visible);
public void visitAttribute(Attribute attr);
public void visitEnd();
}
调用顺序
ClassVisitor 中的方法只能以以下顺序调用,这个顺序也在ClassVisitor的javadoc中说了:
visit visitSource? visitOuterClass? ( visitAnnotation | visitAttribute )*
( visitInnerClass | visitField | visitMethod )*
visitEnd
意思就是必须先调用且调用一次visit方法,然后是0或1次visitSource,然后是0或1次visitOuterClass,然后是0或多次visitAnnotation或visitAttribute,然后是0或多次visitInnerClass或visitField或visitMethod,最后必须调用一次visitEnd。
核心组件
基于ClassVisitor,ASM 提供了3个核心组件用于生成和转换字节码:
- ClassReader类是事件生产者(我们这不是事件模型嘛),它会解析字节数组,调用accept方法。accept方法接收一个ClassVisitor对象,它的各个visitXXX方法会被调用。
- ClassWriter类是事件消费者,它是ClassVisitor的子类,会构建字节码文件。字节数组是通过toByteArray方法产生的。
- ClassVisitor 是事件过滤器,它会把各种请求委托给别的 ClassVisitor 实例。
后面我们开始将它们的用法。
Written on August 2, 2019
分类:
dev,
标签:
java
asm
如果你喜欢,请赞赏!
