asm如何生成子类

我在谷歌上搜索了如何通过asm生成子类,关注这个问题的人似乎很少。这个需求本身不合适吗?或许 asm 最常见的做法是在方法之前和之后添加额外的代码 by AdviceAdapter。我觉得生成子类也是一个很常见的需求,其实做到这一点并不容易。如何让所有公共或受保护的方法自动覆盖父类的方法,就像HttpServletRequest' 子类HttpServletRequestWrapper所做的那样。


我org.ow2.asm:asm:6.2用来实现它如下:


public class InheritMethodVisitor extends ClassVisitor {


/** the return opcode for different type */

public static final Map<Type, Integer> RETURN_OPCODES = new HashMap<>();

/** the load opcode for different type */

public static final Map<Type, Integer> LOAD_OPCODES = new HashMap<>();


static {

    RETURN_OPCODES.put(Type.VOID_TYPE, Opcodes.RETURN);

    RETURN_OPCODES.put(Type.BOOLEAN_TYPE, Opcodes.IRETURN);

    RETURN_OPCODES.put(Type.BYTE_TYPE, Opcodes.IRETURN);

    RETURN_OPCODES.put(Type.SHORT_TYPE, Opcodes.IRETURN);

    RETURN_OPCODES.put(Type.INT_TYPE, Opcodes.IRETURN);

    RETURN_OPCODES.put(Type.LONG_TYPE, Opcodes.LRETURN);

    RETURN_OPCODES.put(Type.FLOAT_TYPE, Opcodes.FRETURN);

    RETURN_OPCODES.put(Type.DOUBLE_TYPE, Opcodes.DRETURN);


    LOAD_OPCODES.put(Type.BOOLEAN_TYPE, Opcodes.ILOAD);

    LOAD_OPCODES.put(Type.BYTE_TYPE, Opcodes.ILOAD);

    LOAD_OPCODES.put(Type.SHORT_TYPE, Opcodes.ILOAD);

    LOAD_OPCODES.put(Type.INT_TYPE, Opcodes.ILOAD);

    LOAD_OPCODES.put(Type.LONG_TYPE, Opcodes.LLOAD);

    LOAD_OPCODES.put(Type.FLOAT_TYPE, Opcodes.FLOAD);

    LOAD_OPCODES.put(Type.DOUBLE_TYPE, Opcodes.DLOAD);

}



private Class<?> superClass;

private ClassVisitor cv;


public InheritMethodVisitor(int api, ClassVisitor classVisitor, Class<?> superClass) {

    super(api);

    this.cv = classVisitor;

    this.superClass = Objects.requireNonNull(superClass);

}


@Override

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

    //Inherit all public or protect methods

    if (Modifier.isStatic(access) || Modifier.isPrivate(access)) return null;

    if (name.equals("<init>") || Modifier.isProtected(access)) access = Opcodes.ACC_PUBLIC;


   

它有效,但不是很容易。事实上,我认为TraceClassVisitor工作很容易。


小唯快跑啊
浏览 180回答 2
2回答

慕桂英4014372

我们使用 ASM 为 Saxon XSLT/XQuery 处理器生成字节码,生成已知抽象类的子类是我们通常做事的方式。我不会假装这很容易,我没有时间给你写教程,很遗憾我不能发布我们的代码,但我可以向你保证这是可能的。我认为您不必为覆盖方法做任何特别的事情。我们有一个类 Generator,它继承了 ASM 的 GeneratorAdapter。我们使用以下内容创建类:&nbsp; &nbsp; String className = "xxx" + compiler.getUniqueNumber();&nbsp; &nbsp; ClassVisitor cv = new ClassWriter(flags);&nbsp; &nbsp; cv.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "com/saxonica/ee/bytecode/iter/CompiledBlockIterator", new String[]{});&nbsp; &nbsp; // CompiledBlockIterator is the superclass name&nbsp; &nbsp; // generate constructor&nbsp; &nbsp; Method m = Method.getMethod("void <init> ()");&nbsp; &nbsp; Generator ga = new Generator(Opcodes.ACC_PUBLIC, m, false, cv);&nbsp; &nbsp; ga.loadThis();&nbsp; &nbsp; ga.invokeConstructor(Type.getType(CompiledBlockIterator.class), m);&nbsp; &nbsp; ga.returnValue();&nbsp; &nbsp; ga.endMethod();然后继续以相同的方式生成其他方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java