我已经开始为我正在处理的编译器项目摆弄 ASM API。但是,我发现文档在很多地方对于新手来说都不够清晰,我认为有一个很好的例子可以生成一个简单地打印“Hello,World!”的类。将是一个很好的例子。
目前,我可以生成一个带有 main() 的类(使用 ClassWriter、ClassVisitor 和 MethodVisitor 类),但我似乎不知道如何生成 main 的主体。谁能给我一个在 ASM 中生成类文件的示例:
- 包含一个 main()
- 在 main() 中创建一个值为“Hello, World!”的本地字符串变量
- 打印变量
最佳答案
您可以使用 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();
}
}
关于java - 使用 Java ASM 库生成 'Hello, World!' 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5346908/