在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()是被调用的最后一个方法,用于提示你访问工作已经结束