资讯详情

MethodVisitor介绍

MethodVisitor介绍

通过调用ClassVisitor类的visitMethod()方法将返回一个MethodVisitor类型对象。

public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions); 

在本文中,我们将MethodVisitor类别介绍:

                                                          ┌─── ClassReader                                                           │                                                           │                                                           │                    ┌─── FieldVisitor                                   ┌─── asm.jar ───────────┼─── ClassVisitor ───┤                                   │                       │                    └─── MethodVisitor                                   │                       │                                   │                       │                    ┌─── FieldWriter                  ┌─── Core API ───┤                       └─── ClassWriter ────┤                  │                │                                            └─── MethodWriter                  │                ├─── asm-util.jar                  │                │ ObjectWeb ASM ───┤                └─── asm-commons.jar                  │                  │                  │                ┌─── asm-tree.jar                  └─── Tree API ───┤                                   └─── asm-analysis.jar 

1. MethodVisitor类

就类结构而言,MethodVisitor类与ClassVisitor类和FieldVisitor类别非常相似。

1.1. class info

第一部分,MethodVisitor类是一个abstract类。

public abstract class MethodVisitor { 
         } 

1.2. fields

第二部分,MethodVisitor类定义的字段是什么?

public abstract class MethodVisitor { 
             protected final int api;     protected MethodVisitor mv; } 

1.3. constructors

第三个部分,MethodVisitor类定义的结构方法有哪些?

public abstract class MethodVisitor { 
             public MethodVisitor
       
        (
        final 
        int api
        ) 
        { 
          
        this
        (api
        , 
        null
        )
        ; 
        } 
        public 
        MethodVisitor
        (
        final 
        int api
        , 
        final 
        MethodVisitor methodVisitor
        ) 
        { 
          
        this
        .api 
        = api
        ; 
        this
        .mv 
        = methodVisitor
        ; 
        } 
        } 
       

1.4. methods

第四个部分,MethodVisitor类定义的方法有哪些。在MethodVisitor类当中,定义了许多的visitXxx()方法,我们列出了其中的一些方法,内容如下:

public abstract class MethodVisitor { 
        
    public void visitCode();

    public void visitInsn(final int opcode);
    public void visitIntInsn(final int opcode, final int operand);
    public void visitVarInsn(final int opcode, final int var);
    public void visitTypeInsn(final int opcode, final String type);
    public void visitFieldInsn(final int opcode, final String owner, final String name, final String descriptor);
    public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor,
                                final boolean isInterface);
    public void visitInvokeDynamicInsn(final String name, final String descriptor, final Handle bootstrapMethodHandle,
                                       final Object... bootstrapMethodArguments);
    public void visitJumpInsn(final int opcode, final Label label);
    public void visitLabel(final Label label);
    public void visitLdcInsn(final Object value);
    public void visitIincInsn(final int var, final int increment);
    public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels);
    public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels);
    public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions);

    public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type);

    public void visitMaxs(final int maxStack, final int maxLocals);
    public void visitEnd();

    // ......
}

对于这些visitXxx()方法,它们分别有什么作用呢?我们有三方面的资料可能参阅:

  • 第一,从ASM API的角度来讲,我们可以查看API文档,来具体了解某一个方法是要实现什么样的作用,该方法所接收的参数代表什么含义。
  • 第二,从ClassFile的角度来讲,这些visitXxxInsn()方法的本质就是组装instruction的内容。我们可以参考Java Virtual Machine Specification的Chapter 6. The Java Virtual Machine Instruction Set部分。
  • 第三,《Java ASM系列二:OPCODE》,主要是对opcode进行介绍。

2. 方法的调用顺序

在MethodVisitor类当中,定义了许多的visitXxx()方法,这些方法的调用,也要遵循一定的顺序。

(visitParameter)*
[visitAnnotationDefault]
(visitAnnotation | visitAnnotableParameterCount | visitParameterAnnotation | visitTypeAnnotation | visitAttribute)*
[
    visitCode
    (
        visitFrame |
        visitXxxInsn |
        visitLabel |
        visitInsnAnnotation |
        visitTryCatchBlock |
        visitTryCatchAnnotation |
        visitLocalVariable |
        visitLocalVariableAnnotation |
        visitLineNumber
    )*
    visitMaxs
]
visitEnd

我们可以把这些visitXxx()方法分成三组:

  • 第一组,在visitCode()方法之前的方法。这一组的方法,主要负责parameter、annotation和attributes等内容,这些内容并不是方法当中“必不可少”的一部分;在当前课程当中,我们暂时不去考虑这些内容,可以忽略这一组方法。
  • 第二组,在visitCode()方法和visitMaxs()方法之间的方法。这一组的方法,主要负责当前方法的“方法体”内的opcode内容。其中,visitCode()方法,标志着方法体的开始,而visitMaxs()方法,标志着方法体的结束。
  • 第三组,是visitEnd()方法。这个visitEnd()方法,是最后一个进行调用的方法。

对这些visitXxx()方法进行精简之后,内容如下:

[
    visitCode
    (
        visitFrame |
        visitXxxInsn |
        visitLabel |
        visitTryCatchBlock
    )*
    visitMaxs
]
visitEnd

这些方法的调用顺序,可以记忆如下:

  • 第一步,调用visitCode()方法,调用一次。
  • 第二步,调用visitXxxInsn()方法,可以调用多次。对这些方法的调用,就是在构建方法的“方法体”。
  • 第三步,调用visitMaxs()方法,调用一次。
  • 第四步,调用visitEnd()方法,调用一次。
                 ┌─── visitCode()
                 │
                 │                      ┌─── visitXxxInsn()
                 │                      │
                 │                      ├─── visitLabel()
                 ├─── visitXxxInsn() ───┤
MethodVisitor ───┤                      ├─── visitFrame()
                 │                      │
                 │                      └─── visitTryCatchBlock()
                 │
                 ├─── visitMaxs()
                 │
                 └─── visitEnd()

3. 总结

本文是对MethodVisitor类进行了介绍,内容总结如下:

  • 第一点,对于MethodVisitor类的各个不同部分进行介绍,以便从整体上来理解MethodVisitor类。
  • 第二点,在MethodVisitor类当中,visitXxx()方法也需要遵循一定的调用顺序。

另外,需要注意两点内容:

  • 第一点,ClassVisitor类有自己的visitXxx()方法,MethodVisitor类也有自己的visitXxx()方法,两者是不一样的,要注意区分。
  • 第二点,ClassVisitor.visitMethod()方法提供的是“方法头”(Method Header)所需要的信息,它会返回一个MethodVisitor对象,这个MethodVisitor对象就用来实现“方法体”里面的代码逻辑。

标签: 二极管dflt48a

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台