ASM 关键接口 MethodVisitor

当ASM的ClassReader读取到Method时就转入MethodVisitor接口处理。
方法的定义,以及方法中指令的定义都会通过MethodVisitor接口通知给程序。我们假设有下面这样的一个类:

下面是这个MethodVisitor接口的所有方法定义。本文只会介绍主要的方法,因此不会逐个对方法做依次介绍:

这些方法必须按照以下顺序调用(和MethodVisitor接口在Javadoc中指定的一些额外约束):

visitAnnotationDefault?
( visitAnnotation | visitParameterAnnotation | visitAttribute )\*
( visitCode
( visitTryCatchBlock | visitLabel | visitFrame | visitXxx Insn | visitLocalVariable | visitLineNumber ) \*
visitMaxs )?
visitEnd

这意味着,如有注释和属性的话,则必须先访问,后面是非抽象方法的字节码。
对于这些方法,这些代码必须按顺序访问,在唯一一个‘visitCode’方法调用和唯一一个‘visitMaxs’方法调用之间。

该接口的方法数量如此之多,甚至是ClassVisitor接口的3倍以上。但是值得关心的接口只有下面这几个,其余的都是和代码有关系:

visitCode

ASM开始扫描这个方法。

visitMaxs(maxStack, maxLocals);

该方法是visitEnd之前调用的方法,可以反复调用。用以确定类方法在执行时候的堆栈大小。

visitEnd();

表示方法输出完毕

因此在一系列的事件中,‘visitCode’方法和‘visitMaxs’方法可以用于检测一个方法字节码的开始和结束。
和class一样,‘visitEnd’方法必须最后调用,并且用于检测在一系列事件中一个方法的结束。

需要注意的是,没有必要为了开始访问另外一个方法,而结束当前访问的方法。
实际上,‘MethodVisitor’实例间是完全独立的,可以用任何顺序调用(但必须在‘cv.visitEnd()’调用之前使用):

ASM提供了三个基于MethodVisitor API的核心组件,用于生成和转换方法:

ClassReader类解析一个编译后的方法,并且通过传递ClassVisitor作为accept方法的参数获得的返回,调用MethodVisitor’相应的方法。
ClassWriter的‘visitMethod’返回了MethodVisitor抽象类的一个实现,该实现可以直接用二进制的方式构建编译后的方法。
MethodVisitor类可以传递所有调用它的方法给另一个MethodVisitor类。MethodVisitor类可以看作一个事件过滤器。

实现类 - MethodWriter

生成相应的“ method_info”结构的MethodVisitor,如Java虚拟机规范(JVMS)中所定义。

发布了409 篇原创文章 · 获赞 1056 · 访问量 52万+

猜你喜欢

转载自blog.csdn.net/qq_33589510/article/details/105273233
ASM
今日推荐