[讨论] eclipse 的bytecode 插件 没有 javap 强大?
xgj1988
2011-04-28
为了方便查看 java class 的 汇编代码,我就装了个bytecode 插件,但是发现好像看不到 常量池的信息。 Compiled from "Test.java" public class Test extends java.lang.Object SourceFile: "Test.java" minor version: 0 major version: 49 Constant pool: const #1 = Method #13.#22; // java/lang/Object."<init>":()V const #2 = Method #5.#23; // java/lang/Integer.valueOf:(I)Ljava/lang/Integer; const #3 = Field #24.#25; // java/lang/System.out:Ljava/io/PrintStream; const #4 = Method #26.#27; // java/io/PrintStream.println:(Ljava/lang/Object;)V const #5 = class #28; // java/lang/Integer const #6 = Method #5.#29; // java/lang/Integer."<init>":(I)V const #7 = String #30; // 1 const #8 = Method #26.#31; // java/io/PrintStream.println:(Ljava/lang/String;)V const #9 = class #32; // java/lang/String const #10 = String #33; // 2 const #11 = Method #9.#34; // java/lang/String."<init>":(Ljava/lang/String;)V const #12 = class #35; // Test const #13 = class #36; // java/lang/Object const #14 = Asciz <init>; const #15 = Asciz ()V; const #16 = Asciz Code; const #17 = Asciz LineNumberTable; const #18 = Asciz main; const #19 = Asciz ([Ljava/lang/String;)V; const #20 = Asciz SourceFile; const #21 = Asciz Test.java; const #22 = NameAndType #14:#15;// "<init>":()V const #23 = NameAndType #37:#38;// valueOf:(I)Ljava/lang/Integer; const #24 = class #39; // java/lang/System const #25 = NameAndType #40:#41;// out:Ljava/io/PrintStream; const #26 = class #42; // java/io/PrintStream const #27 = NameAndType #43:#44;// println:(Ljava/lang/Object;)V const #28 = Asciz java/lang/Integer; const #29 = NameAndType #14:#45;// "<init>":(I)V const #30 = Asciz 1; const #31 = NameAndType #43:#46;// println:(Ljava/lang/String;)V const #32 = Asciz java/lang/String; const #33 = Asciz 2; const #34 = NameAndType #14:#46;// "<init>":(Ljava/lang/String;)V const #35 = Asciz Test; const #36 = Asciz java/lang/Object; const #37 = Asciz valueOf; const #38 = Asciz (I)Ljava/lang/Integer;; const #39 = Asciz java/lang/System; const #40 = Asciz out; const #41 = Asciz Ljava/io/PrintStream;; const #42 = Asciz java/io/PrintStream; const #43 = Asciz println; const #44 = Asciz (Ljava/lang/Object;)V; const #45 = Asciz (I)V; const #46 = Asciz (Ljava/lang/String;)V; { public Test(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 2: 0 public static void main(java.lang.String[]); Code: Stack=3, Locals=5, Args_size=1 0: iconst_1 1: invokestatic #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 4: astore_1 5: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 8: aload_1 9: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V 12: new #5; //class java/lang/Integer 15: dup 16: iconst_1 17: invokespecial #6; //Method java/lang/Integer."<init>":(I)V 20: astore_2 21: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 24: aload_2 25: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V 28: ldc #7; //String 1 30: astore_3 31: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 34: aload_3 35: invokevirtual #8; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 38: new #9; //class java/lang/String 41: dup 42: ldc #10; //String 2 44: invokespecial #11; //Method java/lang/String."<init>":(Ljava/lang/String;)V 47: astore 4 49: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 52: aload 4 54: invokevirtual #8; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 57: return LineNumberTable: line 5: 0 line 6: 5 line 7: 12 line 8: 21 line 9: 28 line 10: 31 line 11: 38 line 12: 49 line 13: 57 }
一个是bytecode 的:
// class version 50.0 (50) // access flags 33 public class Test { // compiled from: Test.java // access flags 1 public <init>()V L0 (0) LINENUMBER 2 L0 ALOAD 0 INVOKESPECIAL java/lang/Object.<init>()V RETURN L1 (4) LOCALVARIABLE this LTest; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 // access flags 9 public static main([Ljava/lang/String;)V L0 (0) LINENUMBER 5 L0 ICONST_1 INVOKESTATIC java/lang/Integer.valueOf(I)Ljava/lang/Integer; ASTORE 1 L1 (4) LINENUMBER 6 L1 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; ALOAD 1 INVOKEVIRTUAL java/io/PrintStream.println(Ljava/lang/Object;)V L2 (8) LINENUMBER 7 L2 NEW java/lang/Integer DUP ICONST_1 INVOKESPECIAL java/lang/Integer.<init>(I)V ASTORE 2 L3 (14) LINENUMBER 8 L3 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; ALOAD 2 INVOKEVIRTUAL java/io/PrintStream.println(Ljava/lang/Object;)V L4 (18) LINENUMBER 9 L4 LDC "1" ASTORE 3 L5 (21) LINENUMBER 10 L5 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; ALOAD 3 INVOKEVIRTUAL java/io/PrintStream.println(Ljava/lang/String;)V L6 (25) LINENUMBER 11 L6 NEW java/lang/String DUP LDC "2" INVOKESPECIAL java/lang/String.<init>(Ljava/lang/String;)V ASTORE 4 L7 (31) LINENUMBER 12 L7 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; ALOAD 4 INVOKEVIRTUAL java/io/PrintStream.println(Ljava/lang/String;)V L8 (35) LINENUMBER 13 L8 RETURN L9 (37) LOCALVARIABLE args [Ljava/lang/String; L0 L9 0 LOCALVARIABLE i Ljava/lang/Integer; L1 L9 1 LOCALVARIABLE i2 Ljava/lang/Integer; L3 L9 2 LOCALVARIABLE x Ljava/lang/String; L5 L9 3 LOCALVARIABLE x2 Ljava/lang/String; L7 L9 4 MAXSTACK = 3 MAXLOCALS = 5 }
而且发现两个编译出来的 文件有点 结构上的不同。。 比如: Code:
和
L0 (0)
都是构造方法 的字节码吧。但是两个的表示就有点不同了。 有时候都搞昏了。 |
|||||||||
xgj1988
2011-04-28
而且还会发现 javap 没有 access flags ,而 bytecode 有access flags 显示。
|
|||||||||
william_ai
2011-04-28
这个。。。
这么玩。O(∩_∩)O哈哈~ 引用 Menu -> Run -> External Tools -> External Tools configurations -> Program -> New
|
|||||||||
xgj1988
2011-04-28
william_ai 写道 这个。。。
这么玩。O(∩_∩)O哈哈~ 引用 Menu -> Run -> External Tools -> External Tools configurations -> Program -> New
虽然你和我问的关系不是很大, 但是,还是 谢谢。但是有个地方我要纠正一下。。 ${workspace_loc}/${project_name}/bin 要用引号双引号,如果是myeclipse 并且创建的是 web project 那么,这里就不是/bin 而是 -verbose -c -classpath "${workspace_loc}/${project_name}/WebRoot/WEB-INF/classes" ${java_type_name} |
|||||||||
william_ai
2011-04-28
xgj1988 写道 ${workspace_loc}/${project_name}/bin 要用引号双引号 只要参数里没有空格,这个双引号是可以不写的。配置的时候有个Note 引用 Enclose an argument containing spaces using double-quotes("). 引用 如果是myeclipse 并且创建的是 web project 那么,这里就不是/bin 而是 -verbose -c -classpath "${workspace_loc}/${project_name}/WebRoot/WEB-INF/classes" ${java_type_name} 最近在鼓捣Eclipse for RCP and RAP Developers版本的Eclipse,所以这么配的。既然提到了web的那就在贴一个Eclipse版本的web的吧Arguments 引用 -verbose -c -classpath ${workspace_loc}/${project_name}/build/classes ${java_type_name} 至于这个目录在哪,可以通过以下方法找到 引用 Project -> Properties -> Java Build Path -> Source -> Default output folder |
|||||||||
william_ai
2011-04-28
估计用的是Andrei Loskutov的那个BytecodeOutLine的eclipse插件吧,其实它生成字节码的部分用的是开源的ASM(Andrei Loskutov也在那个team里),好奇的话,可以到这里看看。
http://asm.ow2.org PS:javap和ASM好像还没有统一风格。。。 |
|||||||||
IcyFenix
2011-04-28
这个一般我都懒得装插件了,就用Eclipse里面的ClassFileViewer
|
|||||||||
igotti
2011-04-28
jclasslib不错,不过没试过能不能加到eclipse里去。
|
|||||||||
xgj1988
2011-04-29
IcyFenix 写道 这个一般我都懒得装插件了,就用Eclipse里面的ClassFileViewer
如果又想看源代码,又想看汇编代码,那就不是很方便了。 |
|||||||||
afeiod
2011-04-29
看汇编代码干嘛用啊。。。。。。。。。。。。。。。。。。。。。。
|