java javap_javap的用途不断发展:您的Java类文件中隐藏了什么?
java javap
什么是Javap,如何使用它以及何時要反匯編類文件?
作為Java開發工具包(JDK)的一部分,我們可以使用許多工具,這些工具有助于更好地理解Java代碼。 這些工具之一是javap命令,它使我們能夠在后臺傳遞Java類文件。
在下面的文章中,我們將研究javap,了解它如何幫助我們并確切地了解我們如何使用它。 代碼,反匯編!
什么是javap?
javap是一個命令行工具,可分解Java類文件:它分解了我們的類文件,并揭示了其中的內容。 該工具將二進制格式的類文件轉換為人類可讀的代碼。 好吧,對于某些人。
javap提供了許多輸出,這些輸出根據我們感興趣的數據而有所不同。默認情況下,javap打印每個類的非私有成員的聲明。
至于javap中的p代表什么,所有證據都指向“打印”,因為javap命令會打印出類中的字節碼。
我們可以使用javap的一種好方法是探索異常。 如果您想提高自己的知識并了解引發異常時會發生什么,請查看我們的帖子,了解有關Java異常的令人驚訝的真相 。
在我們的類中使用javap
既然我們知道了javap是什么,該是在我們的代碼上嘗試使用它的時候了。 我們通過鍵入命令,選擇一個選項并添加類名稱來做到這一點:
javap [選項]類名
正如我們指出的,這些選項(也可以稱為標志)將決定我們的輸出是什么。 我們可以從許多標志中進行選擇,包括:
- -l –輸出行和局部變量表
- -public –僅顯示公共班級和成員
- -protected –僅顯示受保護的和公開的班級和成員
- -package –僅顯示軟件包,受保護的和公共的類和成員
- -p –顯示所有班級和成員
- -Jflag –將標志直接傳遞到運行時系統
- -s –打印內部類型簽名
- -sysinfo –顯示正在處理的類的系統信息(路徑,大小,日期,MD5哈希)
- -constants –顯示靜態最終常量
- -c –打印反匯編的代碼
- -verbose –打印堆棧大小,方法的局部變量和args
用javap深入字節碼
在列出了可以使用javap進行的操作之后,現在該弄清楚它的實際工作方式了。 為此,我們創建了一個名為ExampleClass的基本類:
public class ExampleClass {private int a = 0;private int b = 0;public static void main(String[] args) {System.out.println("Hello world!");} }現在讓我們在javap的幫助下更深入地研究它。 首先,我們將使用不帶任何其他標志的javap命令來打印出非私有成員。 我們的輸出是這樣的:
$ javap ExampleClassCompiled from "ExampleClass.java" public class ExampleClass {public ExampleClass();public static void main(java.lang.String[]); }如您所見,這是原始代碼的漂亮“普通”視圖,沒有有關私有整數和邏輯的任何信息。 這是一個好的開始,但是如果我們想更深入地了解該怎么辦? 讓我們嘗試使用-c打印出反匯編的代碼:
$ javap -c ExampleClassCompiled from "ExampleClass.java" public class ExampleClass {public ExampleClass();Code:0: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: aload_05: iconst_06: putfield #2 // Field a:I9: aload_010: iconst_011: putfield #3 // Field b:I14: returnpublic static void main(java.lang.String[]);Code: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;)V8: return }現在,我們以某種有點可讀的形式保存了字節碼,可以在其中識別我們的方法,整數,命令和字符串。 但是,等等,還有更多。 如果我們需要有關該課程的更多信息怎么辦? 那是我們冗長的標志可以幫助我們的地方:
$ javap -v ExampleClassClassfile /Users/es/ExampleClass.classLast modified May 22, 2017; size 496 bytesMD5 checksum 7d29362228a3128e67b0c20c8bb54ee1Compiled from "ExampleClass.java" public class ExampleClassSourceFile: "ExampleClass.java"minor version: 0major version: 51flags: ACC_PUBLIC, ACC_SUPER Constant pool:#1 = Methodref #8.#20 // java/lang/Object."<init>":()V#2 = Fieldref #7.#21 // ExampleClass.a:I#3 = Fieldref #7.#22 // ExampleClass.b:I#4 = Fieldref #23.#24 // java/lang/System.out:Ljava/io/PrintStream;#5 = String #25 // Hello world!#6 = Methodref #26.#27 // java/io/PrintStream.println:(Ljava/lang/String;)V#7 = Class #28 // ExampleClass#8 = Class #29 // java/lang/Object#9 = Utf8 a#10 = Utf8 I#11 = Utf8 b#12 = Utf8 <init>#13 = Utf8 ()V#14 = Utf8 Code#15 = Utf8 LineNumberTable#16 = Utf8 main#17 = Utf8 ([Ljava/lang/String;)V#18 = Utf8 SourceFile#19 = Utf8 ExampleClass.java#20 = NameAndType #12:#13 // "<init>":()V#21 = NameAndType #9:#10 // a:I#22 = NameAndType #11:#10 // b:I#23 = Class #30 // java/lang/System#24 = NameAndType #31:#32 // out:Ljava/io/PrintStream;#25 = Utf8 Hello world!#26 = Class #33 // java/io/PrintStream#27 = NameAndType #34:#35 // println:(Ljava/lang/String;)V#28 = Utf8 ExampleClass#29 = Utf8 java/lang/Object#30 = Utf8 java/lang/System#31 = Utf8 out#32 = Utf8 Ljava/io/PrintStream;#33 = Utf8 java/io/PrintStream#34 = Utf8 println#35 = Utf8 (Ljava/lang/String;)V {public ExampleClass();flags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: aload_05: iconst_06: putfield #2 // Field a:I9: aload_010: iconst_011: putfield #3 // Field b:I14: returnLineNumberTable:line 1: 0line 3: 4line 4: 9public static void main(java.lang.String[]);flags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=1, args_size=10: 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;)V8: returnLineNumberTable:line 7: 0line 8: 8 }很多行在我們面前展開。 我們可以看到以下內容:
1.元數據–此類文件的位置,上次修改時間以及具有其唯一ID的類哈希
2.常量池–結構表,它引用ClassFile結構及其子結構中的各種常量。 它保存類,接口,類實例,字段名稱,字符串常量或數組的符號信息。
3.字節碼–用JVM可以“讀取”的語言編寫的指令集
在OverOps,我們使用javap作為研究工具來挖掘類內部。 我們最近使用它來發現IBM J9的工作方式,為使用此JVM的開發人員提供支持。 如果您想了解更多有關我們如何幫助團隊減少調試時間并知道代碼在何時何地中斷的原因, 請單擊此處以安排演示 。
現在我們知道了如何使用javap,是時候回答一個重要的問題了:
到底有什么好處呢?
Javap很酷,特別是如果您是像我們這樣的數據迷并且想知道代碼背后發生了什么時。 但是除了不錯的代碼探索冒險外,它也非常有用。
對于原始源代碼不可用的情況,它可能會派上用場,其中顯示了可以使用的方法。 它還可以幫助找出別人的代碼或3rd party類中的內容。
我們還可以將javap用作Java類的類驗證器,以確保每個加載的類文件都以適當的方式進行結構化。
剛開始,javap就像是一根魔杖,可以在代碼內為我們提供所有信息,但它并不是對我們所面臨的每個問題的完整解決方案。 它可能會幫助“逆向工程”某些代碼,但這更多是一個復雜難題的線索。
如果您正在尋找一種將javap字節碼輸出轉換為功能性Java代碼的方法,而不僅僅是“數據列表”,那么您將需要反編譯工具(如JD , Mocha等)的幫助。
最后的想法
盡管您不會經常使用它,但是javap是一個有用的工具,請牢記。 除了它是一個很酷的“技巧”之外,它還更深入地介紹了Java代碼,向我們展示了幕后發生的事情以及JVM如何使用我們的代碼。
翻譯自: https://www.javacodegeeks.com/2017/06/javap-usage-unfolds-whats-hidden-inside-java-class-files.html
java javap
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的java javap_javap的用途不断发展:您的Java类文件中隐藏了什么?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谷歌 Pixel 8 / Pro 手机全
- 下一篇: 手机被ddos攻击该怎么办(手机遭到dd