我已经开始乱用我正在处理的编译器项目的ASM API。但是,我发现文档对于很多地方的新手来说还不太清楚,我认为有一个很好的例子来生成一个简单打印“Hello,World!”的类。这将是一个很好的例子。
目前,我可以使用main()生成一个类(使用ClassWriter,ClassVisitor和MethodVisitor类),但我似乎无法弄清楚如何生成main的主体。任何人都可以给我一个在ASM中生成类文件的示例:
答案 0 :(得分:13)
您可以使用java编译一个类,然后使用asm打印出生成等效类所需的调用,
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();
}
}
答案 1 :(得分:9)
如果您使用的是Eclipse,那么有一个很棒的ASM plugin可以帮助您学习。它将现有Java代码显示为检测所述代码所需的实际ASM调用。它非常有用,因为您可以看到实现特定Java代码所需的ASM调用。