美文网首页
13 - ASM之MethodVisitor

13 - ASM之MethodVisitor

作者: 舍是境界 | 来源:发表于2022-01-23 08:54 被阅读0次

通过调用ClassVisitor类的visitMethod()方法,会返回一个MethodVisitor类型的对象。在本文当中,我们就对MethodVisitor类进行介绍。

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

MethodVisitor类

从类的结构来说,MethodVisitor类与ClassVisitor类和FieldVisitor类是非常相似性。

class info

MethodVisitor类是一个abstract类。

public abstract class MethodVisitor {
}
fields

MethodVisitor类定义的字段:

public abstract class MethodVisitor {
    protected final int api;
    protected MethodVisitor mv;
}
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;
    }
}
methods

在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

方法的调用顺序

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

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

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

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

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

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

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

  1. 调用visitCode()方法,调用一次。
  2. 调用visitXxxInsn()方法,可以调用多次。对这些方法的调用,就是在构建方法的“方法体”。
  3. 调用visitMaxs()方法,调用一次。
  4. 调用visitEnd()方法,调用一次。

小结

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

相关文章

网友评论

      本文标题:13 - ASM之MethodVisitor

      本文链接:https://www.haomeiwen.com/subject/iuezcrtx.html