插入ClassVisitors链我在ClassReader和ClassWriter之间无法控制?

时间:2013-02-27 17:29:08

标签: java-bytecode-asm

public class ChainingVisitors {
    public static void main(String[] args) throws Exception {
        ClassReader reader = new ClassReader("com.foo.Bar");
        ClassWriter writer = new ClassWriter(COMPUTE_MAXS | COMPUTE_FRAMES);
        ClassVisitor v3 = new Link(3, writer);
        ClassVisitor v2 = new Link(2, v3);
        ClassVisitor v1 = new Link(1, v2);
        reader.accept(v1, 0);
        System.out.printf("how many bytes in %s? %d\n", Runnable.class, writer.toByteArray().length);
    }

    private static class Link extends ClassVisitor {
        private final int order;

    public Link(int order, ClassVisitor next) {
        super(ASM4, next);
        this.order = order;
    }

    @Override public void visit(int i, int i2, String s, String s2, String s3, String[] strings) {
        System.out.printf("In visitor %d\n", order);
        super.visit(i, i2, s, s2, s3, strings);
    }
}

我想将一个ClassVisitor的任意链子交给一个方法。该方法将通过ClassReader读取类的字节,依次使用ClassVisitors转换类,并通过ClassWriter写入结果。基本上,我想使用这些访问者的链(我假设,我无法控制)“介于”ClassReaderClassWriter之间,该方法将控制其实例化。

我该怎么做?似乎访问者的链接要求您从“后面”(最后一个链接,绑定到ClassWriter)到“前面”(第一个链接,accept()由{{1}构建链。 }})。

2 个答案:

答案 0 :(得分:2)

我会争辩这样的设计。如果某个组件能够创建访问者,为什么它不能在传递给它的字节码上运行ClassReader和ClassWriter?

但如果您真的想自己创建访客链,可以使用工厂设计模式。因此,不是访问者,而是通过工厂创建这些访问者,然后您可以自己构建访问链,而无需了解访问者。

答案 1 :(得分:1)

您可以尝试将访问者类传递给您的方法,并通过反射在那里实例化它们。