【问题标题】:Generating a 'Hello, World!' class with the Java ASM library生成“你好,世界!”带有 Java ASM 库的类
【发布时间】:2011-07-17 20:13:59
【问题描述】:

我已经开始为我正在处理的编译器项目使用 ASM API。但是,我发现文档对于很多地方的新手来说都不是很清楚,我认为有一个很好的可靠示例来生成一个简单地打印“Hello, World!”的类。将是一个很好的例子。

目前,我可以使用 main() 生成一个类(使用 ClassWriter、ClassVisitor 和 MethodVisitor 类),但我似乎无法弄清楚如何生成 main 的主体。谁能给我一个在 ASM 中生成类文件的示例:

  • 包含一个 main()
  • 在 main() 中创建一个值为“Hello, World!”的局部字符串变量
  • 打印变量

【问题讨论】:

    标签: java compilation bytecode jvm-languages java-bytecode-asm


    【解决方案1】:

    如果您使用的是 Eclipse,有一个很棒的ASM plugin 可以帮助您学习。它将现有 Java 代码显示为检测所述代码所需的实际 ASM 调用。它对学习非常有用,因为您可以看到实现特定 Java 代码所需的 ASM 调用。

    【讨论】:

    • 我更关心 ASM API 调用来生成字节码,但无论如何我一定会检查一下。
    【解决方案2】:

    您可以使用 java 编译一个类,然后让 asm 打印出生成等效类所需的调用,

    FAQ

    ASMifierClassVisitor

    ASMifierClassVisitor javadocs 实际上有 hello world 代码,

    import org.objectweb.asm.*;
    
    public class HelloDump implements Opcodes {
    
      public static byte[] dump() throws Exception {
    
         ClassWriter cw = new ClassWriter(0);
         FieldVisitor fv;
         MethodVisitor mv;
         AnnotationVisitor av0;
    
         cw.visit(49,
                 ACC_PUBLIC + ACC_SUPER,
                 "Hello",
                 null,
                 "java/lang/Object",
                 null);
    
         cw.visitSource("Hello.java", null);
    
         {
             mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
             mv.visitVarInsn(ALOAD, 0);
             mv.visitMethodInsn(INVOKESPECIAL,
                     "java/lang/Object",
                     "<init>",
                     "()V");
             mv.visitInsn(RETURN);
             mv.visitMaxs(1, 1);
             mv.visitEnd();
         }
         {
             mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
                     "main",
                     "([Ljava/lang/String;)V",
                     null,
                     null);
             mv.visitFieldInsn(GETSTATIC,
                     "java/lang/System",
                     "out",
                     "Ljava/io/PrintStream;");
             mv.visitLdcInsn("hello");
             mv.visitMethodInsn(INVOKEVIRTUAL,
                     "java/io/PrintStream",
                     "println",
                     "(Ljava/lang/String;)V");
             mv.visitInsn(RETURN);
             mv.visitMaxs(2, 1);
             mv.visitEnd();
         }
         cw.visitEnd();
    
         return cw.toByteArray();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      • 2011-06-29
      • 2011-03-06
      • 2015-01-13
      • 1970-01-01
      相关资源
      最近更新 更多