最近呢,給自己定了些小目標(其實就是列了下近期想要學習的東西一些列表)
其中一個,就是java的字節碼的解析。
說是解析,其實就是研究研究字節碼,並且能看懂一些簡單的字節碼文件。
前言:
我覺得作爲一個java工程師(雖然我領導說我java很菜,算不上寫java的),還是要對字節碼有所瞭解的,這樣更能夠加深自己對java的理解,對代碼運行過程的理解,甚至有一些奇奇怪怪的面試題(就寫了一段代碼,問你會return或者打印什麼值)通過字節碼也可以解釋的通,不然很多題目都是通過結果來推過程(儘管反推也是一種可行的方法,但如果能提前知道過程和原因,推測結果,然後運行程序,發現預測的一樣,不就更有成就感,也能提升自己的水平!!)
(我覺得)學習的順序:
1、一些簡單的概念,例如什麼是字節碼,如何查看,java爲什麼能在各種環境下運行等基礎問題
2、字節碼指令(通過javap得到的字節碼的相關指令)
3、類的字節碼中有哪些模塊
4、瞭解每個模塊中的信息,看懂較爲基礎的代碼編譯出來的字節碼
5、研究一些比較特殊的語法糖的實現(包括java,scala等需要編譯成class文件的語言)
但是其實,關於字節碼的相關資料真的挺多的,這篇文章我猶豫了很久才寫,畢竟偏理論性的文章,寫出來會和其他文章如出一轍。所以最後決定文章的大綱由我自己擬定,接着會引用他人的文章的部分,來組成該博客(我會標明作者的!!)
正文:
我們寫好的以java爲後綴的文件,可以通過javac這個命令來編譯成class文件,class文件可以通過反編譯工具變回代碼(不過並不會變成一模一樣的代碼,會和原來的有所區別,但是功能肯定是一樣的),也可以通過javap的命令來獲得字節碼信息。嗯~到這裏,簡單的概念我就不囉嗦了,大家百度都能百度到啊!!
1、如果想對java的JVM模型深入瞭解:
https://dzone.com/articles/introduction-to-java-bytecode(作者:Mahmoud Anouti)
如果要讓我概括個大概的話,就是當你要操作一個加法的時候,需要將數字A加載到操作數堆棧(英文原文爲:operand stack),然後把數字B也加載到操作數堆棧,將操作數堆棧中的兩個值pop(彈出),進行相加,把結果push回操作數堆棧,最後pop出剛纔的結果值,存到本地變量中(建議大家直接看英文原文,因爲各個翻譯版本不盡相同,容易引起誤會)
2、字節碼命令
JVM Class詳解之二 Method字節碼指令:
https://yq.aliyun.com/articles/7242?spm=a2c4e.11155435.0.0.790d367cULERDq(作者:nothingismao)
該文已經寫的非常詳細,並且分類,條理清晰,主要需要記住哪些指令是把數值加入到操作數堆棧,哪些是彈出的(哪些是入棧哪些是出棧的)!其他的一些邏輯判斷,主要是看有沒有行數的跳轉!
如圖(行數跳轉):
3、類的字節碼中包含的模塊
講道理,我根本記不全,因爲有些模塊其實不影響我們對字節碼執行順序的解讀,這部分推薦大家將自己的代碼反編譯一下,做一個大概的瞭解即可,如下兩篇文章有些內容可能會重複,重複的跳着看就好~
https://yq.aliyun.com/articles/7241?spm=a2c4e.11155435.0.0.790d367cx67aXN(作者:nothingismao)
https://www.jianshu.com/p/247e2475fc3a(作者:Windy_816)
4、提升:
如果你想要有更多字節碼的案例,以下的文章可以滿足你!
有一位國外的大神有開這個坑(但是他坑還沒填完):
http://blog.jamesdbloom.com/JavaCodeToByteCode_PartOne.html(作者:James Bloom)
http://blog.jamesdbloom.com/JavaCodeToByteCode_PartTwo.html(作者:James Bloom)
建議最好看原文,當然也有csdn上也有翻譯的版本,也可以參考着看,他的其他文章也都很不錯~!有空可以多看看其他的