ASM:输出java字节码和操作码

我正在尝试编写一个带有.class文件的程序,并收集.class文件的所有方法以及每个方法的内容。 这是我的代码

public class ClassReaderTest1 { public static void main(String[] args) throws Exception{ InputStream in = new FileInputStream("*.class"); ClassReader reader = new ClassReader(in); ClassNode classNode = new ClassNode(); reader.accept(classNode,0); @SuppressWarnings("unchecked") final List methods = classNode.methods; for(MethodNode m: methods){ InsnList inList = m.instructions; System.out.println(m.name); for(int i = 0; i< inList.size(); i++){ System.out.println(" " + Integer.toHexString(inList.get(i).getOpcode())); } } } } 

这是我的输出

 init> ffffffff ffffffff 19 b7 b1 ffffffff main ffffffff ffffffff b2 12 b6 ffffffff ffffffff 3 36 ffffffff ffffffff b1 ffffffff 

最终我不想打印这些值,我只是希望能够在我的程序中引用它们(我正在尝试检查我是否得到了正确的值)。 我按预期获得方法,但方法的内容对我没有意义。 我认为这些不是操作码; 特别是“fffffff”不是java操作码。 我想要做的是打印出我上面所做的所有方法,然后我现在拥有操作码,打印出java字节码后跟几个空格然后是操作码。 例如

 main bytecode ** . . 

我加载到此程序中的文件只包含一个main方法,一个println语句和一个int变量的初始化。

我的问题是我做错了什么,还是我不正确地解释我的结果? 另外,我怎样才能获得字节码? 我无法找到一种方法来获得它。 当我使用eclipse的java字节码大纲插件时,我可以看到它,但我需要能够在我的程序中引用它。

提前致谢

我能够自己解决这个问题。 我发布了我的解决方案,以防其他人遇到同样的问题。 请注意,在我的实现中,我不打印出操作码(只需要添加一个println语句来执行此操作)。

 import java.io.InputStream; import java.io.FileInputStream; import java.io.StringWriter; import java.io.PrintWriter; import java.util.List; import org.objectweb.asm.*; import org.objectweb.asm.tree.*; import org.objectweb.asm.util.*; public class ClassReaderTest1 { public static void main(String[] args) throws Exception{ InputStream in = new FileInputStream("*afile*"); ClassReader reader = new ClassReader(in); ClassNode classNode = new ClassNode(); reader.accept(classNode,0); @SuppressWarnings("unchecked") final List methods = classNode.methods; for(MethodNode m: methods){ InsnList inList = m.instructions; System.out.println(m.name); for(int i = 0; i< inList.size(); i++){ System.out.print(insnToString(inList.get(i))); } } } public static String insnToString(AbstractInsnNode insn){ insn.accept(mp); StringWriter sw = new StringWriter(); printer.print(new PrintWriter(sw)); printer.getText().clear(); return sw.toString(); } private static Printer printer = new Textifier(); private static TraceMethodVisitor mp = new TraceMethodVisitor(printer); } 

这是产生的输出

  L0 LINENUMBER 1 L0 ALOAD 0 INVOKESPECIAL java/lang/Object. ()V RETURN L1 main L2 LINENUMBER 3 L2 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; LDC "Hello World!!!" INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V L3 LINENUMBER 4 L3 ICONST_0 ISTORE 1 L4 LINENUMBER 5 L4 RETURN L5