我正在寻找一个轻松允许我查看方法的给定字节码的库。例如:
ALOAD 0
INVOKEVIRTUAL ns/c.m ()I
IRETURN
我试过了两个:
答案 0 :(得分:4)
有关打印字节码详细信息的示例,请查看ASM和TraceClassVisitor
的TraceMethodVisitor
来源。
这是一个简单的测试类:
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.util.TraceClassVisitor;
public class Main {
public static void main(String[] args) throws Exception {
if (1 > args.length) {
System.err.println("No arguments.");
return;
}
InputStream is = Main.class.getResourceAsStream(args[0]);
ClassReader cr = new ClassReader(is);
cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), 0);
}
}
哪些输出(以Main.class
作为参数传递时):
// class version 50.0 (50)
// access flags 0x21
public class Main {
// compiled from: Main.java
// access flags 0x1
public <init>()V
L0
LINENUMBER 11 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x9
public static main([Ljava/lang/String;)V throws java/lang/Exception
L0
LINENUMBER 13 L0
ICONST_1
ALOAD 0
ARRAYLENGTH
IF_ICMPLE L1
L2
LINENUMBER 14 L2
GETSTATIC java/lang/System.err : Ljava/io/PrintStream;
LDC "No arguments."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L3
LINENUMBER 15 L3
RETURN
L1
LINENUMBER 17 L1
FRAME SAME
LDC LMain;.class
ALOAD 0
ICONST_0
AALOAD
INVOKEVIRTUAL java/lang/Class.getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream;
ASTORE 1
L4
LINENUMBER 18 L4
NEW org/objectweb/asm/ClassReader
DUP
ALOAD 1
INVOKESPECIAL org/objectweb/asm/ClassReader.<init> (Ljava/io/InputStream;)V
ASTORE 2
L5
LINENUMBER 19 L5
ALOAD 2
NEW org/objectweb/asm/util/TraceClassVisitor
DUP
NEW java/io/PrintWriter
DUP
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
INVOKESPECIAL java/io/PrintWriter.<init> (Ljava/io/OutputStream;)V
INVOKESPECIAL org/objectweb/asm/util/TraceClassVisitor.<init> (Ljava/io/PrintWriter;)V
ICONST_0
INVOKEVIRTUAL org/objectweb/asm/ClassReader.accept (Lorg/objectweb/asm/ClassVisitor;I)V
L6
LINENUMBER 28 L6
RETURN
MAXSTACK = 6
MAXLOCALS = 3
}
答案 1 :(得分:1)
其中,ASM是唯一支持最新Java版本的人。关于访问者,您可能需要阅读this tutorial。它是为旧版ASM API编写的,但访问者概念仍然相同。