ASM框架學習(二)-ClassVisitor

簡介

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:訪問類的尾部,只有當類訪問結束時,才能調用該方法,同時必須調用該方法;


作者:技術蝸牛
鏈接:https://www.jianshu.com/p/dcc9ffcf9c8e
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章