字節碼?原來如此!

目錄

什麼是字節碼?

字節碼文件內容如下:

字節碼結構

魔數:

版本號: 

Access_flags訪問標誌

當前類名

父類名稱

接口信息

字段表

方法表

附加屬性表

有哪些操作查看字節碼?

第一步: javac A.java 編譯生成 A.class

第二步: 使用 javap -c A.class 或 javap -verbose A.class 都可查看字節碼文件


原文鏈接:https://blog.csdn.net/mengfanzhundsc/article/details/106365027

  • 什麼是字節碼?

    • 字節碼(Byte-code)是一種包含執行程序、由一序列 op 代碼/數據對組成的二進制文件。字節碼是一種中間碼,它比機器碼更抽象。它經常被看作是包含一個執行程序的二進制文件,更像一個對象模型。字節碼被這樣叫是因爲通常每個 opcode 是一字節長,但是指令碼的長度是變化的。每個指令有從 0 到 255(或十六進制的: 00 到FF)的一字節操作碼,被參數例如寄存器或內存地址跟隨。 - 來自《百度百科》;
    • 各種不同平臺的虛擬機與所有平臺都統一使用的程序存儲格式——字節碼(ByteCode)是構成平臺無關性的基石。
    • 字節碼文件內容如下:

  • 字節碼結構

  • 魔數:

    • 對應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 都可查看字節碼文件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章