一、Java虛擬機的組成
二、字節碼文件的組成
字節碼文件的組成 – 應用場景
字節碼文件的組成部分-Magic魔數
什么是魔數?
Java字節碼文件中的魔數
文件是無法通過文件擴展名來確定文件類型的,文件擴展名可以隨意修改,不影響文件的內容。
軟件使用文件的頭幾個字節(文件頭)去校驗文件的類型,如果軟件不支持該種類型就會出錯。
Java字節碼文件中,將文件頭稱為magic魔數。
字節碼文件的組成部分-主副版本號
- 主副版本號指的是編譯字節碼文件的JDK版本號,主版本號用來標識大版本號,JDK1.0-1.1使用了45.0-45.3,JDK1.2是46之后每升級一個大版本就加1;副版本號是當主版本號相同時作為區分不同版本的標識,一般只需要關心主版本號。
- 版本號的作用主要是判斷當前字節碼的版本和運行時的JDK是否兼容。
1.2之后大版本號計算方法就是:
主版本號 – 44
比如主版本號52就是JDK8
常見問題
需求:解決以下由于主版本號不兼容導致的錯誤
兩種方案:
1.升級JDK版本
2.將第三方依賴的版本號降低或者更換依賴,以滿足JDK版本的要求
(容易引發其他的兼容性問題,并且需要大量的測試)
√ 建議采用
字節碼文件的組成 – 基礎信息
字節碼文件的組成部分-常量池
字節碼文件中常量池的作用:避免相同的內容重復定義,節省空間。
- 常量池中的數據都有一個編號,編號從1開始。在字段或者字節碼指令中通過編號可以快速的找到對應的數據。
- 字節碼指令中通過編號引用到常量池的過程稱之為符號引用。
一個非常有意思的面試題
面試官:int i = 0; i = i++; 最終i的值是多少?
答:應該是1吧,i++優先級高,先執行之后將返回結果1賦值給 i,所以最終 i應該是1。
面試官:這個答案是不對的,最終i的值還是0。
字節碼文件的組成部分-方法
字節碼中的方法區域是存放字節碼指令的核心位置,字節碼指令的內容存放在方法的Code屬性中。
操作數棧是臨時存放數據的地方,局部變量表是存放方法中的局部變量的位置。
- i=i++的執行流程:
- i=++i的執行流程:
- 通過分析方法中的字節碼指令,我們成功的解決了這個問題
面試官:int i = 0; i = i++; 最終i的值是多少?
我:答案是0,我通過分析字節碼指令發現,i++先把0取出來放入臨時的操作數棧中,接下來對i進行加1,i變成了1,最后再將之前保存的臨時值0放入i,最后i就變成了0。
面試官:非常好!