[讨论] eclipse 的bytecode 插件 没有 javap 强大?

xgj1988 2011-04-28

为了方便查看 java class 的 汇编代码,我就装了个bytecode 插件,但是发现好像看不到 常量池的信息。

下面是代码对比:
一个是命名行的
javap -verbose Test

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:
   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

 

 

 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

 

都是构造方法 的字节码吧。但是两个的表示就有点不同了。 有时候都搞昏了。

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

Namejavap -c
Location/usr/bin/javap
Working Directory${workspace_loc}/${project_name}
Arguments-verbose -c -classpath ${workspace_loc}/${project_name}/bin ${java_type_name}


xgj1988 2011-04-28
william_ai 写道
这个。。。

这么玩。O(∩_∩)O哈哈~
引用
Menu -> Run -> External Tools -> External Tools configurations -> Program -> New

Namejavap -c
Location/usr/bin/javap
Working Directory${workspace_loc}/${project_name}
Arguments-verbose -c -classpath ${workspace_loc}/${project_name}/bin ${java_type_name}




虽然你和我问的关系不是很大,
但是,还是 谢谢。但是有个地方我要纠正一下。。

${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
看汇编代码干嘛用啊。。。。。。。。。。。。。。。。。。。。。。
Global site tag (gtag.js) - Google Analytics