Java 如果存在注释,则向转换的类添加接口
我正在使用asm框架的Java 如果存在注释,则向转换的类添加接口,java,instrumentation,java-bytecode-asm,Java,Instrumentation,Java Bytecode Asm,我正在使用asm框架的ClassAdapter编写字节码转换器。如果类上存在自定义注释,我希望添加一些方法并使该类实现一个接口。添加这些方法很好,但我想知道让类实现接口的最佳方法是什么。由于visitanotation仅在visit之后调用,因此我需要以某种方式延迟调用超级访问方法,并将所有需要的信息缓冲到那时 有人实现过类似的东西吗?尽管软件包文档建议尽可能避免使用asm的树api,但我是否应该使用它 以下是转换的一般结构: public class MyClassAdapter extend
ClassAdapter
编写字节码转换器。如果类上存在自定义注释,我希望添加一些方法并使该类实现一个接口。添加这些方法很好,但我想知道让类实现接口的最佳方法是什么。由于visitanotation
仅在visit
之后调用,因此我需要以某种方式延迟调用超级访问方法,并将所有需要的信息缓冲到那时
有人实现过类似的东西吗?尽管软件包文档建议尽可能避免使用asm的树api,但我是否应该使用它
以下是转换的一般结构:
public class MyClassAdapter extends ClassAdapter {
private String classname;
private boolean instrument;
public PropertyChangeSupportAdapter(ClassVisitor cv) {
super(cv);
}
@Override
public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
this.classname = name;
}
@Override
public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
if (desc.equals("Lmypackage/MyAnnotation;")) {
instrument = true;
System.out.println("Instrumenting " + classname);
}
return super.visitAnnotation(desc, visible);
}
@Override
public void visitEnd() {
if (instrument) {
// add methods
}
}
}
我最终使用了ClassNode和ClassAdapter API的组合。首先,将类文件解析为类节点:
ClassReader cr = new ClassReader(inputStream);
ClassNode cn = new ClassNode();
cr.accept(cn, 0);
然后可以检查cn.visibleAnnotation或cn.invibleAnnotations是否包含我的注释,以及类是否已经实现了我要添加的接口。在这种情况下,可以跳过第二步。然后可以使用ClassAdapter api转换ClassNode,如问题所示:
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
CheckClassAdapter ca = new CheckClassAdapter(cw);
ClassVisitor cv = new PropertyChangeSupportAdapter(ca);
cn.accept(cv);
来自的注释(这是我提出问题的原因)提到了这些API之间的一个巨大性能差异:
使用ClassAdapter读取、修改和编写类的速度几乎是使用ClassNode读取、修改和编写类的速度的两倍。。。这也是为什么在可能的情况下建议不要使用此类适配器的原因
再次阅读之后,差异似乎来自于使用类节点来操作字节码。但是,我没有对这个混合解决方案进行基准测试