日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java字节码解读

發布時間:2025/3/19 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java字节码解读 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java最重要的一個機制就是虛擬機JVM,通過執行編譯好的字節碼.class文件,可以實現跨平臺的可移植性,那么小伙伴們會不會好奇字節碼文件是怎樣的,它是怎么工作的?參考來源,為了便于回顧,特此按自己思路重頭來一遍,接下來我們就一起來解讀一下字節碼文件,前方高能,大腦請提前清空。

?

1. 前期準備

1.1 首先編寫一個測試程序,簡單地在main方法中聲明一個Integer包裝類型變量i和一個基本類型int類型變量n,代碼如下。

public class EnTest {public static void main(String[] args) {Integer i = 10;int n = i;} }

1.2 命令行javac編譯得到.class字節碼文件

1.3 安裝二進制文件編輯器,博主使用Notepad++,可參照我的另一篇博客,你也可以使用其它編輯器。

?

2. 打開字節碼文件

2.1 使用安裝HexEditor插件的Notepad++打開字節碼文件,需要說明的是,文件中都是16進制,所以兩位剛好是一個字節,如下圖。

?

2.2 按照對照表分析字節碼文件

2.2.1 從文件取4個字節【ca fe ba be】得到第一塊內容,文件類型

最先的4個字節ca fe ba be代表了字節碼文件的類型,只要是class文件,開頭的四個字節就是cafebabe,音譯咖啡寶貝也就是java的logo熱騰騰的咖啡。

?

2.2.2接著從文件取2+2個字節【00 00 00 3b】?得到第二塊內容,java版本

其中開始的【00 00】這兩個字節的十進制是0,代表,次版本號是0,;然后【00 3b】的十進制是59,代表主版本號是15,所以我的java版本是java 15

?

2.2.3接著取2+n個字節得到第三塊內容——常量池

先取兩個字節00 19,化為十進制為25,表示有25項常量,但是第一項常量是系統預留,所以是24項常量,下圖是常量對應表,每一個常量由兩三項數據構成,但是每一項常量的第一個數據都是一個字節大小,所以接下來我們取一個字節

?

2.2.3.1 第一項常量,取一個字節【0a】

0a十進制是10,根據值是10確定常量類型是CONSTANT_Methodref_info,它的第二項數據占兩個字節,是索引,表示指向第幾項常量。取接下來的兩個字節【00 02】十進制是2,表示指向第2項常量,現在還沒求第二項常量,看后面。然后第三項數據也是占兩個字節,也是索引,再取接下來的【00 03】十進制是3,表示指向第3項常量,現在還沒求第三項常量,第一項常量結束。

?

2.2.3.2第二項常量,取一個字節【07】

07十進制是7,根據7確定常量類型是CONSTANT_class_info,它的第二項數據占兩個字節,是索引,也表示指向第幾項常量,取接下來的兩個字節【00 04】十進制是4,指向第4項常量,第2項常量結束。

?

2.2.3.3第三項常量,取一個字節【0c】

0c十進制是12,根據值是12確定常量類型是CONSTANT_NameAndType_info,它的第二項數據占兩個字節,是索引,表示指向第幾項常量。取接下來的兩個字節【00 05】十進制是5,表示指向第5項常量。然后第三項數據也是占兩個字節,也是索引,再取接下來的【00 06】十進制是6,表示指向第6項常量,第3項常量結束。

?

2.2.3.4第四項常量,取一個字節【01】

01十進制是1,根據值是1確定常量類型是CONSTANT_Utf8_info,它的第二項數據占兩個字節,是長度length。取接下來的兩個字節【00 10】十進制是16,表示長度是16。然后第三項數據占一個字節,是長度為length=16的字符串,取接下來的【6a 61 76 61 2f 6c?61 6e 67 2f 4f 62 6a 65 63 74】轉化為十進制,然后根據ASCII碼轉化為一個個字符,字符串使用程序計算如下圖,得到“java/lang/Object”,第4項常量結束。

?

2.2.3.5第5項常量,取一個字節【01】?

01十進制是1,根據值是1確定常量類型是CONSTANT_Utf8_info,它的第二項數據占兩個字節,是長度length。取接下來的兩個字節【00 06】十進制是6,表示長度是6。然后第三項數據占一個字節,是長度為length=6的字符串,取接下來的【3c 69 6e ?69 74 3e 】轉化為十進制,然后根據ASCII碼轉化為一個個字符,字符串使用程序計算如下圖,得到“<init>”,第5項常量結束。

?

2.2.3.6第6項常量,取一個字節【01】?

01十進制是1,根據值是1確定常量類型是CONSTANT_Utf8_info,它的第二項數據占兩個字節,是長度length。取接下來的兩個字節【00 03】十進制是3,表示長度是3。然后第三項數據占一個字節,是長度為length=3的字符串,取接下來的【28?29 56】轉化為十進制,然后根據ASCII碼轉化為一個個字符,字符串使用程序計算如下圖,得到“()V”,第6項常量結束。

?

2.2.3.7?第7項常量,取一個字節【0a】

0a十進制是10,根據值是10確定常量類型是CONSTANT_Methodref_info,它的第二項數據占兩個字節,是索引,表示指向第幾項常量。取接下來的兩個字節【00 08】十進制是8,表示指向第8項常量,現在還沒求第8項常量,看后面。然后第三項數據也是占兩個字節,也是索引,再取接下來的【00 09】十進制是9,表示指向第9項常量,現在還沒求第9項常量,第7項常量結束。

?

……………………………………………………………………

……………………………………………………………………

?

以此類推可以得到其它17項常量,我就不一一推導了,使用javap -v EnTest命令得到反編譯內容得到常量池內容和常量池解讀結束位置如下圖。

?

2.2.4根據對照表第四塊內容訪問標志位,取兩個字節【00 21】

【00 21】表示0x0020和0x0001進行或操作得到,訪問屬性表如下圖所示,即表示類屬性是public和繼承了父類(默認繼承Object類)。

?

2.2.5根據對照表得到第5塊內容本類名稱,取兩個字節【00 11】

【00 11】十進制是17,表示此處從第17項常量獲得值,而且第17項常量指向第18項常量,第18項常量值為“EnTest”,代表本類名稱為“EnTest”。

?

2.2.6根據對照表得到第6塊內容父類名稱,取兩個字節【00 11】

【00 02】十進制是2,此處從第2項常量獲得值,而且第2項常量指向第4項常量,第4項常量值為“java/lang/Object”,代表父類名稱為“java/lang/Object”。

?

2.2.7根據對照表得到第7塊內容接口信息,先取兩個字節【00 00】

【00 00】表示接口數量為0,第7塊內容結束。

?

2.2.8根據對照表得到第8塊內容類級別變量信息,先取兩個字節【00 00】

該處描述類和接口的變量,不包括方法中的局部變量,我們只定義了兩個變量,所以此處為0,如果有類級別變量,可以安裝下圖字段表進行解析。

?

2.2.9根據對照表得到第9塊內方法信息,先取兩個字節【00 02】

?

【00 02】十進制是2,表示有兩個方法,但我們只有一個main方法,我們接下來根據方法表來推斷一下另一個方法。

先取兩個字節【00 01】,該處是訪問標志符,根據訪問屬性表可知0x0001表示public,其次取兩個字節【00 05】十進制是5,表示從常量池取第5項常量值得到方法名“<init>”,然后取兩個字節【00 06】十進制是6,表示從常量池取第6項常量值得到方法描述"()V",接著取兩個字節【00 01】十進制是1,表示有一個屬性,需要根據屬性表進行解析,屬性表如下圖。

先取兩個字節表示屬性名字在常量池的索引,取兩個字節【00 13】十進制是19,第19項的值是“Code”,所以屬性名稱是“Code”,既然是Code屬性,虛擬機就會需要調用Code屬性表,不再使用上述屬性表結構解讀。

由于Code屬性表第二項的屬性長度要4個字節,則取4個字節【00 00 00 1d】十進制是29,長度 是29,所以往后29個字節都是該Code屬性的內容。接下來取兩個字節【00 01】表示max_stack=1,再取兩個字節【00 01】表示max_locals=1,再取4個字節【00 00 00 05】表示字節碼指令長度是5,接下來5個字節【2a b7 20 01 b1 ?】具體意思就不展開了,由于后續解析內容涉及更多屬性表內容,但是平時又不大涉及,故不多多講解,到此結束解讀。

?

?

最終使用javap -v EnTest反編譯的部分字節碼內容如下。

?

?

總結

以上是生活随笔為你收集整理的Java字节码解读的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。