Создание "Привет, мир!" класс с библиотекой ASM Java

Я начал общаться с API ASM для проекта компилятора, над которым я работаю. Тем не менее, я нахожу, что документация во многих местах не так понятна для новичков, и я подумал, что у меня хороший пример создания класса, который просто печатает "Hello, World!". будет отличным примером для этого.

В настоящее время я могу сгенерировать класс с помощью main() (используя классы ClassWriter, ClassVisitor и MethodVisitor), но я не могу понять, как сгенерировать основной объект. Может ли кто-нибудь дать мне пример создания файла класса в ASM, который:

  • содержит main()
  • создает локальную переменную String в main() со значением "Hello, World!"
  • печатает переменную

Ответ 1

Вы можете скомпилировать класс с помощью java, а затем получить asm, чтобы распечатать вызовы, которые потребуется для создания эквивалентного класса,

FAQ

ASMifierClassVisitor

В javadocs ASMifierClassVisitor на самом деле есть глобальный код hello,

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();
  }
}

Ответ 2

Если вы используете Eclipse, есть отличный плагин ASM, который поможет вашему обучению. Он отображает существующий код Java как фактические вызовы ASM, необходимые для работы с указанным кодом. Это очень полезно для обучения, поскольку вы можете видеть вызовы ASM, необходимые для реализации определенного кода Java.