Skip to content

Latest commit

 

History

History
executable file
·
65 lines (49 loc) · 2.35 KB

7.2组件合成.md

File metadata and controls

executable file
·
65 lines (49 loc) · 2.35 KB

7.2 组件合成

前为止,我们仅看到了如何创建和转换 MethodNode 对象,却还没有看到与类的字节数组表示进行链接。和类的情景一样,这一链接过程也是通过合成核心 API 和树 API 组件完成的,本节就来进行解释。

7.2.1 介绍

除了图 7.1 显示的字段之外,MethodNode 类扩展了 MethodVisitor 类,还提供了两个 accept 方法,它以一个 MethodVisitor 或一个 ClassVisitor 为参数。accept 方法基于 MethodNode 字段值生成事件,而 MethodVisitor 方法执行逆操作,即根据接收到的事件设定 MethodNode 字段。

7.2.2 模式

和类的情景一样,有可能与核心 API 使用一个基于树的方法转换器,比如一个方法适配器。用于类的两种模式实际上对于方法也是有效的,其工作方式完全相同。基于继承的模式如下:

public class MyMethodAdapter extends MethodNode {
    public MyMethodAdapter(int access, String name, String desc, String signature, String[] exceptions, MethodVisitor mv) {
        super(ASM4, access, name, desc, signature, exceptions);
        this.mv = mv;
    }

    @Override
    public void visitEnd() {
        // 将你的转换代码放在这儿
        accept(mv);
    }
}

而基于委托的模式为:

public class MyMethodAdapter extends MethodVisitor {
    MethodVisitor next;

    public MyMethodAdapter(int access, String name, String desc, String signature, String[] exceptions, MethodVisitor mv) {
        super(ASM4,
                new MethodNode(access, name, desc, signature, exceptions));
        next = mv;
    }

    @Override
    public void visitEnd() {
        MethodNode mn = (MethodNode) mv;
        //将你的转换代码放在这儿
        mn.accept(next);
    }
}

第一种模式的一种变体是直接在 ClassAdapter 的 visitMethod 中将它与一个匿名内部类一起使用:

public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    return new MethodNode(ASM4, access, name, desc, signature, exceptions) {
        @Override
        public void visitEnd() {
            //将你的转换代码放在这儿
            accept(cv);
        }
    };
}

这些模式表明,可以将树 API 仅用于方法,将核心 API 用于类。在实践中经常使用这一策略