目錄
第一步: javac A.java 編譯生成 A.class
第二步: 使用 javap -c A.class 或 javap -verbose A.class 都可查看字節碼文件
原文鏈接:https://blog.csdn.net/mengfanzhundsc/article/details/106365027
-
什麼是字節碼?
-
字節碼結構
-
魔數:
- 對應Test.class 字節碼文件中,魔數是0XCAFE BABE 。是用來區分文件類型的一種標誌,一般都是用文件的前幾個字節來表示。比如0XCAFE BABE表示的是class 文件。因爲文件名包括後綴是可以修改的,所以爲了保證文件的安全性,將文件類型寫入了文件內容中來保證不被篡改。翻譯過來就是咖啡寶貝意思,和Java 咖啡logo 保持呼應。
-
版本號:
- 版本號含主版本號和次版本號。都各佔2個字節byte 。
- 對應Test.class 字節碼文件中,版本號是0X0000 0034 。其中前面0000是副版本號minor_version,後面0034 是主版本號major_version。
- 進制轉換後副版本號0,主版本號52. 從oralce 官網得知,52對應的正式jdk1.8 ,次版本號爲0,所以該文件的版本爲1.8.0 。
- 參考如下:
-
Access_flags訪問標誌
- Access_flags 描述的事當前類(或接口)的訪問修飾符。如public,private等
-
當前類名
- 訪問標誌後的兩個字節,描述的是當前類的全限定名。這兩個字節保存的值爲常量池中的索引值,根據索引值就能在常量池中找到這個類的全限定名。
-
父類名稱
- 當前類名後的兩個字節,描述父類的全限定名,同上,保存的也是常量池中的索引值。
-
接口信息
- 父類名稱後爲兩字節的接口計數器,描述了該類或父類實現的接口數量。緊接着 的 n 個字節是所有接口名稱的字符串常量的索引值。
-
字段表
- fields_info 用於描述接口或者類中聲明的變量、字段包括類級以及實例級變量,但是不包括在方法內部聲明的局部變量;
- 第一部分爲字段計數器,佔兩個字節,描述字段個數;
- 第二部分是每個字段的詳細信息 fields_info。結構如下:
- name_index:表示field 的名稱-字段名
- descriptor_index:表示field的類型描述符(字段類型描述符)用來描述字段的數據類型,方法的參數列表和返回值
- 字段的訪問標誌:
-
方法表
- 方法表結構:
- 第一部分:方法計數器,佔兩個字節,描述方法個數;
- 第二部分:方法數據區,描述方法的詳細信息,結構如下:
- name_index: 方法名稱
- descriptor_index: 方法描述符,描述方法的參數列表返回值等,參數列表在前 返回值在後
- 執行命令 javap -verbose A.class 將其反編譯爲解讀,可見方法數據區的內容分爲3個部分:
- “Code 區”:源代碼對應的JVM 指令操作碼,在進行字節碼增強時重點操作的就是“Code 區”這一部分。
- “LineNumberTable”:行號表, 將 Code 區的操作碼和源代碼中的行號對應,Debug 時會起到作用(源代碼走一行,需要走多少個 JVM 指令操作碼)。
- “LocalVariableTable”:本地變量表,包含 This 和局部變量,之所以可以在每一個方法內部都可以調用This, 是因爲 JVM 將 This 作爲每一個方法的第 一個參數隱式進行傳入。當然,這是針對非 Static 方法而言。
-
附加屬性表
- 字節碼的最後一部分,該項存放了在該文件中類或接口所定義屬性的基本信息。
-
有哪些操作查看字節碼?
-
第一步: javac A.java 編譯生成 A.class
-
第二步: 使用 javap -c A.class 或 javap -verbose A.class 都可查看字節碼文件
-