【问题标题】:Java bytecode generation with generic signature information from reflect.Method使用来自 reflect.Method 的通用签名信息生成 Java 字节码
【发布时间】:2013-06-05 20:57:53
【问题描述】:

我正在尝试对 java.lang.reflect.Method 进行字节码生成方法签名。它的签名(通用类型)部分很棘手,因为反射 api 获取类型信息并将其转换为 asm 需要的内容并不简单。知道那里的任何代码已经这样做了吗?

【问题讨论】:

    标签: java assembly


    【解决方案1】:

    我不知道有什么工具可以自动执行此操作。我可能会使用 org.objectweb.asm.util.ASMifierClassVisitor 类来确定签名和 ASM API 调用之间的关系。

    对于包含此代码的类:

      public void foo1(Object o1, String s2) {
      }
    

    ...工具将生成:

    mv = cw.visitMethod(ACC_PUBLIC, "foo1",
         "(Ljava/lang/Object;Ljava/lang/String;)V", null, null);
    mv.visitCode();
    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 3);
    mv.visitEnd();
    

    对于此代码:

      public static final String[] foo2() {
        return null;
      }
    

    ...它将生成:

    mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL + ACC_STATIC,
        "foo2", "()[Ljava/lang/String;", null, null);
    mv.visitCode();
    mv.visitInsn(ACONST_NULL);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(1, 0);
    mv.visitEnd();
    

    method signatures in the FAQ 上有注释,如果你理解Java class nomenclature 会有所帮助。

    请注意,ASM API 也可用于将 java.lang.reflect.Method 转换为 org.objectweb.asm.commons.Method。由于您可以从 java.lang.reflect.Methodget the class,因此您可以使用 ClassVisitors / MethodVisitors 到 inspect the methods

    【讨论】:

    • 嗯,我一直在寻找一种直接从反射 api 获取而不使用 asm 重新解析类文件的方法。泛型的反射 api 变得棘手
    • 好的,我想我明白了——我不确定是否会有一种万能的方法。如果一个方法返回一个值,你需要在其中加入一些逻辑以使其有效(假设它不是抽象的)。
    【解决方案2】:

    我建议使用现有的库,例如:

    【讨论】:

      【解决方案3】:

      我想我正在尝试做一些非常相似的事情 (Generating methods with generic types with Asm bytecode generator (ClassWriter))。

      从类访问者的 visitMethod 中,我可以看到该方法如下:

      public List<String> foobar(List<Integer> args, List<Boolean> args2);
      

      将产生如下描述:

        (Ljava/util/List;Ljava/util/List;)Ljava/util/List;
      

      (如预期的那样,没有泛型信息)

      签名如下:

        (Ljava/util/List<Ljava/lang/Integer;>;Ljava/util/List<Ljava/lang/Boolean;>;)Ljava/util/List<Ljava/lang/String;>;
      

      (添加了泛型)

      因此生成通用签名以增加非通用描述应该是相当直接的。它与在源代码中添加泛型信息的方式非常相似,除了处理单字符原始类型时引入的奇怪之处。

      我还没有尝试过,但是鉴于 ClassWriter 的 visitMethod() 也需要签名,我希望它会起作用。 :)

      【讨论】:

      • 对于它的价值,虽然这看起来应该有效,但似乎没有。问题是ASM本身添加了它,并且可以看到它,但是由于某种原因,JVM的反射方法似乎没有找到它。 :-/
      【解决方案4】:

      尝试使用 spring-asm 库(例如 Type.getType(String.class))

      【讨论】:

        猜你喜欢
        • 2015-09-01
        • 2015-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-18
        • 2013-02-02
        • 1970-01-01
        • 2016-12-30
        相关资源
        最近更新 更多