为了账号安全,请及时绑定邮箱和手机立即绑定

asm如何生成子类

asm如何生成子类

小唯快跑啊 2021-05-31 08:31:49
我在谷歌上搜索了如何通过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);}@Overridepublic 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工作很容易。
查看完整描述

2 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

我们使用 ASM 为 Saxon XSLT/XQuery 处理器生成字节码,生成已知抽象类的子类是我们通常做事的方式。我不会假装这很容易,我没有时间给你写教程,很遗憾我不能发布我们的代码,但我可以向你保证这是可能的。我认为您不必为覆盖方法做任何特别的事情。


我们有一个类 Generator,它继承了 ASM 的 GeneratorAdapter。


我们使用以下内容创建类:


    String className = "xxx" + compiler.getUniqueNumber();

    ClassVisitor cv = new ClassWriter(flags);

    cv.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null,

            "com/saxonica/ee/bytecode/iter/CompiledBlockIterator", new String[]{});

    // CompiledBlockIterator is the superclass name


    // generate constructor


    Method m = Method.getMethod("void <init> ()");

    Generator ga = new Generator(Opcodes.ACC_PUBLIC, m, false, cv);

    ga.loadThis();

    ga.invokeConstructor(Type.getType(CompiledBlockIterator.class), m);

    ga.returnValue();

    ga.endMethod();

然后继续以相同的方式生成其他方法。


查看完整回答
反对 回复 2021-06-02
  • 2 回答
  • 0 关注
  • 175 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信