您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java的javap工具怎么使用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Java的javap工具怎么使用”吧!
一:簡介
javap是JDK自帶的反匯編器,可以查看java編譯器為我們生成的字節(jié)碼。通過它,我們可以對(duì)照源代碼和字節(jié)碼,從而了解很多編譯器內(nèi)部的工作。
javap命令的常用參數(shù)有:
-l 打印行和本地變量表
-public 只顯示公共類和成員變量
-protected 只顯示公共的、受保護(hù)的類和變量
-private 顯示所有的類和成員變量
-p 顯示所有的類和成員變量
-Joption 給jvm指定參數(shù),例如:
javap -J-version
javap -J-Djava.security.manager -J-Djava.security.policy=MyPolicy
-s 打印內(nèi)部類型簽名(用于泛型)
-sysinfo 打印被處理類的系統(tǒng)信息(路徑,大小,日志,MD5哈希)
-constants 顯示static final常量
-c 輸出分解后的代碼。例如,類中每一個(gè)方法內(nèi),包含java字節(jié)碼的指令
-verbose 輸出棧大小,變量(locals)和方法參數(shù)的個(gè)數(shù)
-classpath path 指定查詢類的路徑.如果設(shè)置該值,則會(huì)覆蓋默認(rèn)值和CLASSPATH環(huán)境變量。
-bootclasspath path 指定啟動(dòng)類的路徑,默認(rèn)值是jre/lib/rt.jar 和 其他少數(shù)的jar.
-extdir dirs 覆蓋 java.ext.dirs路徑
二:實(shí)例
1.Java源代碼
public class Demo { private String name = "張三"; public static void main(String args[]) { System.out.println("Hello World."); } private void sayHello() { System.out.println("Hello " + name); } }
2.javac編譯后的字節(jié)碼
CA FE BA BE 00 00 00 34 00 36 0A 00 0D 00 1E 08 00 1F 09 00 0C 00 20 09 00 21 00 22 08 00 23 0A 00 24 00 25 07 00 26 0A 00 07 00 1E 08 00 27 0A 00 07 00 28 0A 00 07 00 29 07 00 2A 07 00 2B 01 00 04 6E 61 6D 65 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00 04 74 68 69 73 01 00 28 4C 63 6F 6D 2F 62 72 69 6C 6C 69 61 6E 74 73 74 61 72 2F 63 69 6D 63 2F 69 6D 2F 64 65 73 6B 74 6F 70 2F 44 65 6D 6F 3B 01 00 04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 08 73 61 79 48 65 6C 6C 6F 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 44 65 6D 6F 2E 6A 61 76 61 0C 00 10 00 11 01 00 06 E5 BC A0 E4 B8 89 0C 00 0E 00 0F 07 00 2C 0C 00 2D 00 2E 01 00 0C 48 65 6C 6C 6F 20 57 6F 72 6C 64 2E 07 00 2F 0C 00 30 00 31 01 00 17 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 42 75 69 6C 64 65 72 01 00 06 48 65 6C 6C 6F 20 0C 00 32 00 33 0C 00 34 00 35 01 00 26 63 6F 6D 2F 62 72 69 6C 6C 69 61 6E 74 73 74 61 72 2F 63 69 6D 63 2F 69 6D 2F 64 65 73 6B 74 6F 70 2F 44 65 6D 6F 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01 00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 06 61 70 70 65 6E 64 01 00 2D 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 42 75 69 6C 64 65 72 3B 01 00 08 74 6F 53 74 72 69 6E 67 01 00 14 28 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 00 21 00 0C 00 0D 00 00 00 01 00 02 00 0E 00 0F 00 00 00 03 00 01 00 10 00 11 00 01 00 12 00 00 00 39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 12 02 B5 00 03 B1 00 00 00 02 00 13 00 00 00 0A 00 02 00 00 00 13 00 04 00 14 00 14 00 00 00 0C 00 01 00 00 00 0B 00 15 00 16 00 00 00 09 00 17 00 18 00 01 00 12 00 00 00 37 00 02 00 01 00 00 00 09 B2 00 04 12 05 B6 00 06 B1 00 00 00 02 00 13 00 00 00 0A 00 02 00 00 00 17 00 08 00 18 00 14 00 00 00 0C 00 01 00 00 00 09 00 19 00 1A 00 00 00 02 00 1B 00 11 00 01 00 12 00 00 00 4B 00 03 00 01 00 00 00 1D B2 00 04 BB 00 07 59 B7 00 08 12 09 B6 00 0A 2A B4 00 03 B6 00 0A B6 00 0B B6 00 06 B1 00 00 00 02 00 13 00 00 00 0A 00 02 00 00 00 1B 00 1C 00 1C 00 14 00 00 00 0C 00 01 00 00 00 1D 00 15 00 16 00 00 00 01 00 1C 00 00 00 02 00 1D
3.javap返匯編后的內(nèi)容
javap -p -v Demo
默認(rèn)情況下javap會(huì)打印所有非私有的字段和方法,當(dāng)加了-p選項(xiàng)后,它還將打印私有的字段和方法;-v 它盡可能地打印所有信息。如果只需要查詢方法對(duì)應(yīng)的字節(jié)碼,那么可以用-c代替-v.
=================基本信息(涵蓋了原class文件的相關(guān)信息)======================= Classfile /D:/workspace/donkey/cimc-im-desktop/target/classes/com/brilliantstar/cimc/im/desktop/Demo.class Last modified 2018-9-6; size 909 bytes MD5 checksum 0f9cd841c4a2ab1f6a00163e55ca6e0f Compiled from "Demo.java" public class com.brilliantstar.cimc.im.desktop.Demo minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER =================常量池(用來存放各種常量及符號(hào)引用)======================= Constant pool: #1 = Methodref #13.#30 // java/lang/Object."<init>":()V #2 = String #31 // 張三 #3 = Fieldref #12.#32 // com/brilliantstar/cimc/im/desktop/Demo.name:Ljava/lang/String; #4 = Fieldref #33.#34 // java/lang/System.out:Ljava/io/PrintStream; #5 = String #35 // Hello World. #6 = Methodref #36.#37 // java/io/PrintStream.println:(Ljava/lang/String;)V #7 = Class #38 // java/lang/StringBuilder #8 = Methodref #7.#30 // java/lang/StringBuilder."<init>":()V #9 = String #39 // Hello #10 = Methodref #7.#40 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #11 = Methodref #7.#41 // java/lang/StringBuilder.toString:()Ljava/lang/String; #12 = Class #42 // com/brilliantstar/cimc/im/desktop/Demo #13 = Class #43 // java/lang/Object #14 = Utf8 name #15 = Utf8 Ljava/lang/String; #16 = Utf8 <init> #17 = Utf8 ()V #18 = Utf8 Code #19 = Utf8 LineNumberTable #20 = Utf8 LocalVariableTable #21 = Utf8 this #22 = Utf8 Lcom/brilliantstar/cimc/im/desktop/Demo; #23 = Utf8 main #24 = Utf8 ([Ljava/lang/String;)V #25 = Utf8 args #26 = Utf8 [Ljava/lang/String; #27 = Utf8 sayHello #28 = Utf8 SourceFile #29 = Utf8 Demo.java #30 = NameAndType #16:#17 // "<init>":()V #31 = Utf8 張三 #32 = NameAndType #14:#15 // name:Ljava/lang/String; #33 = Class #44 // java/lang/System #34 = NameAndType #45:#46 // out:Ljava/io/PrintStream; #35 = Utf8 Hello World. #36 = Class #47 // java/io/PrintStream #37 = NameAndType #48:#49 // println:(Ljava/lang/String;)V #38 = Utf8 java/lang/StringBuilder #39 = Utf8 Hello #40 = NameAndType #50:#51 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #41 = NameAndType #52:#53 // toString:()Ljava/lang/String; #42 = Utf8 com/brilliantstar/cimc/im/desktop/Demo #43 = Utf8 java/lang/Object #44 = Utf8 java/lang/System #45 = Utf8 out #46 = Utf8 Ljava/io/PrintStream; #47 = Utf8 java/io/PrintStream #48 = Utf8 println #49 = Utf8 (Ljava/lang/String;)V #50 = Utf8 append #51 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #52 = Utf8 toString #53 = Utf8 ()Ljava/lang/String; { ===============字段區(qū)域(用來列舉該類中的各個(gè)字段)=================== private java.lang.String name; descriptor: Ljava/lang/String; flags: ACC_PRIVATE public com.brilliantstar.cimc.im.desktop.Demo(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: ldc #2 // String 張三 7: putfield #3 // Field name:Ljava/lang/String; 10: return LineNumberTable: line 19: 0 line 20: 4 LocalVariableTable: Start Length Slot Name Signature 0 11 0 this Lcom/brilliantstar/cimc/im/desktop/Demo; ===============方法區(qū)域(用來列舉該類中的各個(gè)方法)========================= public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #5 // String Hello World. 5: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 23: 0 line 24: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 args [Ljava/lang/String; private void sayHello(); descriptor: ()V flags: ACC_PRIVATE Code: stack=3, locals=1, args_size=1 0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 3: new #7 // class java/lang/StringBuilder 6: dup 7: invokespecial #8 // Method java/lang/StringBuilder."<init>":()V 10: ldc #9 // String Hello 12: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 15: aload_0 16: getfield #3 // Field name:Ljava/lang/String; 19: invokevirtual #10 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: invokevirtual #11 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 25: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 28: return LineNumberTable: line 27: 0 line 28: 28 LocalVariableTable: Start Length Slot Name Signature 0 29 0 this Lcom/brilliantstar/cimc/im/desktop/Demo; } SourceFile: "Demo.java"
以其中的sayHello()方法為例,除了方法描述以及訪問權(quán)限之外,方法中還包括最為重要的代碼區(qū)域。
1).代碼區(qū)域一開始會(huì)聲明該方法中的操作數(shù)棧(stack=3) 和局部變量數(shù)目(locals=1)的最大值,以及該方法接收參數(shù)的個(gè)數(shù)(args_size=1)這里局部變量指的是字節(jié)碼中的局部變量,而非Java程序中的局部變量。
2).接下來是該方法的字節(jié)碼,每條字節(jié)碼均標(biāo)注了對(duì)應(yīng)的偏移量,這是用來定位字節(jié)碼的。
3).接下來的行數(shù)表(LineNumberTable)則是Java源程序到字節(jié)碼偏移量的映射。行數(shù)表和局部變量均屬于調(diào)試信息,Java虛擬機(jī)并不要求class文件必備這些信息。
感謝各位的閱讀,以上就是“Java的javap工具怎么使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Java的javap工具怎么使用這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。