ASM之ClassVistor
在ASM core API中,最重要的三个类就是ClassReader、ClassVistor、ClassWriter
ClassVistor是一个抽象类,如果要使用必须继承它,比较常见的官方实现的子类有ClassWriter类和ClassNode类
ClassVistor的构造方法:
public abstract class ClassVisitor {
/**
* @param api ASM的版本,填最新的ASM9.0即可
**/public ClassVisitor(final int api) {this(api, null);}public ClassVisitor(final int api, final ClassVisitor classVisitor) {this.api = api;this.cv = classVisitor;}
}
ClassVistor定义的方法:
public abstract class ClassVisitor {
/*** 这个方法对应class文件的基本结构,详情参考class的基本结构
**/public void visit(final int version,final int access,final String name,final String signature,final String superName,final String[] interfaces);
/**
* 这个方法对应class文件的属性
**/public FieldVisitor visitField( // 访问字段final int access,final String name,final String descriptor,final String signature,final Object value);
/**
* 这个方法对饮class文件的方法
**/public MethodVisitor visitMethod( // 访问方法final int access,final String name,final String descriptor,final String signature,final String[] exceptions);public void visitEnd();// ......
}
ClassVistor方法的调用顺序
visit
[visitSource][visitModule][visitNestHost][visitPermittedSubclass][visitOuterClass]
(visitAnnotation |visitTypeAnnotation |visitAttribute
)*
(visitNestMember |visitInnerClass |visitRecordComponent |visitField |visitMethod
)*
visitEnd
这些方法按顺序调用,其中的符号含义如下
[]: 表示最多调用一次,可以不调用,但最多调用一次。
()和|: 表示在多个方法之间,可以选择任意一个,并且多个方法之间不分前后顺序。
*: 表示方法可以调用0次或多次。
我们平时最常用的四个visit方法
visit
(visitField |visitMethod
)*
visitEnd
visit()对应的class结构如下
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];
}
visitField()对应的class结构如下
field_info {u2 access_flags;u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count];
}
visitMethod()对饮的class结构如下
method_info {u2 access_flags;u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count];
}
visitEnd()是被调用的最后一个方法,用于提示你访问工作已经结束