ASM框架学习(二)-ClassVisitor
2019-05-16 本文已影响0人
奔跑地蜗牛
简介
ClassVisitor是用来生成asm和改变字节码的,ClassVisitor是一个访问字节码的框架,其对字节码的创建和修改主要是通过其内部的ClassVisitor具体实现来代理的;
ClassVisitor对一个java类的访问是有一定顺序的,其具体顺序如下:
visit [visitSource] [visitModule] [visitNestHost][visitOuterClass](visitAnnotation | visitTypeAnnotation|visitAttribute)*
(visitNestMember|visitInnerClass|visitField| visitMethod)* visitEnd;
说明:visit,visitEnd必须调用一次,[]表示最多调用一次;
()*表示()里面的访问可以按照排列顺序调用多次;
方法说明
- visit:访问类的头部,
public void visit(final int version,final int access, final String name, final String signature, final String superName, final String[] interfaces){
if (cv != null) {
cv.visit(version, access, name, signature, superName, interfaces);
}};
其中version指的是类的版本;
acess指的是类的修饰符;
name类的名称;
signature类的签名,如果类不是泛型或者没有继承泛型类,那么signature为空;
superName类的父类名称;
- visitSource: 访问类的源码,就是.java文件,一般情况用不上;
public void visitSource(final String source, final String debug) {
if (cv != null) {
cv.visitSource(source, debug);
}
}
- visitModule:暂时不清楚用来干嘛的,用的比较少;
- visitNestHost:访问类的nest host;
nest 指的一个共享私有成员变量的包名相同的class集合,nest中有一个host(主类)和多个members(成员类),jdk11为了提供更大,更广泛的嵌套类型,并且为了补足访问控制检测不足,引进了两个新的class文件属性,nest host 和nest member,nest host中包含了一个nest members列表,用来确定其他静态nest members;nest member中包含了一个nest host属性用来确定它的nesthost;
- visitOuterClass: 访问类的外部类,一般用于nest-class;
- visitAnnotation:访问类的注解;
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
if (cv != null) {
return cv.visitAnnotation(descriptor, visible);
}
return null;
}
其中:
descriptor:表示类注解类的描述;
visible表示该注解是否运行时可见;
return AnnotationVisitor:表示该注解类的Visitor,可以用来访问注解值;
- visitTypeAnnotation:访问类的签名类型(某个泛型)的注解;
public AnnotationVisitor visitTypeAnnotation(
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
if (api < Opcodes.ASM5) {
throw new UnsupportedOperationException("This feature requires ASM5");
}
if (cv != null) {
return cv.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
}
return null;
}
其中:
typeRef:指的是类型引用,在这里只能是TypeReference.(CLASS_TYPE_PARAMETER |CLASS_TYPE_PARAMETER_BOUND|CLASS_EXTENDS );
typePath:被注解的类型参数,wildcard bound,array element type,包含typeRef的static inner type;
descriptor: 注解类的描述;
visible:该注解类型运行时是否可见;
- visitAttribute:访问类的非标准属性;
public void visitAttribute(final Attribute attribute) {
if (cv != null) {
cv.visitAttribute(attribute);
}
}
- visitNestMember:访问嵌套类的nest member,只有host class被visited时才能调用该方法
- visitInnerClass:访问一个内部类的信息;
- visitField:访问一个类的域信息,如果需要修改或者新增一个域,可以通过重写此方法;
public FieldVisitor visitField( final int access, final String name, final String descriptor,final String signature,
final Object value) {
if (cv != null) {
return cv.visitField(access, name, descriptor, signature, value);
}
return null;
}
其中
access:表示该域的访问方式,public,private或者static,final等等;
name:指的是域的名称;
descriptro:域的描述,一般指的是该field的参数类型;
signature:指的是域的签名,一般是泛型域才会有签名;
value:指的该域的初始值
reture FiedVisitor:表示将返回一个可以访问该域注解和属性的访问对象,如果不感兴趣的话,可以设置为空;
- visitMethod:访问类的方法,如果需要修改类方法信息,则可以重写此方法;
public MethodVisitor visitMethod( final int access,final String name,final String descriptor,final String signature, final String[] exceptions) {
if (cv != null) {
return cv.visitMethod(access, name, descriptor, signature, exceptions);
}
return null;
}
其中:
decsriptor:表示方法的参数类型和返回值类型;
- visitEnd:访问类的尾部,只有当类访问结束时,才能调用该方法,同时必须调用该方法;