本文地址ASM
字节码操纵框架ASM
Jacoco注入探针来进行覆盖率分析,主要使用的是ASM库。ASM是Java字节码操纵框架,它能够读取class文件,改变类行为,分析类信息,甚至能够生成自定义的新类。
ASM中核心类
- ClassReader:该类用来解析字节码class文件,具体可以直接由字节组或者class文件间接的获得字节码数据。可以调用accept方法,这个方法接受一个实现了ClassVisitor接口的对象作为参数,然后依次调用ClassVisitor接口的各个方法。
- ClassWriter:该类实现了ClassVisitor接口,用来重新构建编译后的类(是框架的核心部分),比如说修改类名、属性以及方法,生成新的字节码文件。具体而言,它可以以二进制的方式创建一个类的字节码,对于ClassWriter的每一个方法的调用会创建类的相应部分,例如调用visit方法会创建一个类的声明部分,调用visitMethod方法就会在这个类中创建一个新的方法,调用visitEnd方法表明对于该类的创建已经完成了。它最终会通过toByteArray方法返回一个数组,这个数组包含了整个class文件的完整字节码内容。
- ClassAdapter:该类也实现了ClassVisitor接口,其构造刚发需要ClassVisitor对象,并保存字段为protected ClassVisitor cv。在它的实现中,每个方法都是原装不动的调用cv的对应方法,并传递同样的参数。可以通过继承ClassAdapter并修改其中的部分方法达到过滤的作用,它可以看成事件的过滤器
ClassVisitor
抽象类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();
}
MethodVisitor
abstract class MethodVisitor { // public accessors ommited
MethodVisitor(int api);
MethodVisitor(int api, MethodVisitor mv);
AnnotationVisitor visitAnnotationDefault();
AnnotationVisitor visitAnnotation(String desc, boolean visible);
AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible);
void visitAttribute(Attribute attr);
//Starts the visit of the method's code, if any (i.e. non abstract method).
//访问函数开始时调用
void visitCode();
void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack);
// Visits a zero operand instruction.