.java文件編譯過程和執(zhí)行過程分析以及計(jì)算機(jī)簡單認(rèn)識(shí)

一個(gè).java文件的"沉浮"之路

本文全為原創(chuàng)內(nèi)容,轉(zhuǎn)載請(qǐng)注明出處:http://www.reibang.com/p/af78a314c6fc

1:引言:

由于昨天的網(wǎng)絡(luò)問題请梢,導(dǎo)致分享做的不是特別好力穗。所以老薛這里寫了一份分
享的筆記毅弧,希望可以幫助那些沒有聽課的同學(xué)稍稍彌補(bǔ)一下。

昨天的分享大概分為一下幾個(gè)模塊來講解的:

i:分享初衷
ii:分享內(nèi)容大綱
iii:建議
iv:一個(gè).java文件的沉浮之路
    a:什么是計(jì)算機(jī)当窗?
    b:計(jì)算機(jī)發(fā)展歷史
    c:.java文件如何變?yōu)?class文件
    d:.class文件如何被JVM加載形真,加載內(nèi)容如何解析
    e:jvm和操作系統(tǒng)和底層硬件的簡單交互。

2:分享初衷:

很多人遇到一個(gè)很尷尬的問題:一看就會(huì)超全,一問就懵咆霜,一敲就傻。
新技術(shù)層出不窮,到底學(xué)習(xí)什么救军?如何取舍拷泽。
業(yè)務(wù)代碼很多聋迎,編寫代碼不夠優(yōu),不知道如何增加自己的硬編碼實(shí)例。
每天都很忙谷浅,不知道如何利用自己的碎片化時(shí)間武裝自己的知識(shí)體系蛹锰。

基于以上內(nèi)容竹海,希望能夠找到一些技術(shù)。分享給大家,而這些技術(shù)必須具備如下特征:

可能實(shí)用價(jià)值不高,但是希望能夠在未來很長一段時(shí)間對(duì)你而言都有幫助

可以很好的和目前的編碼統(tǒng)一起來,不能由于新的技術(shù)加入,導(dǎo)致和目前的學(xué)習(xí)工作沒有關(guān)系

3:分享內(nèi)容大綱

基于剛才的內(nèi)容,我大概在自己有限的學(xué)習(xí)數(shù)據(jù)庫中整理了一下。我會(huì)在以下內(nèi)容開始分享:

‘瞎’侃計(jì)算機(jī)組成與系統(tǒng)結(jié)構(gòu)
‘胡’說數(shù)據(jù)結(jié)構(gòu)和算法
‘嗨’聊計(jì)算機(jī)網(wǎng)絡(luò)
實(shí)戰(zhàn)編碼:
    你真的會(huì)寫代碼嗎? 如何寫出優(yōu)雅高效的代碼!
    什么是面向?qū)ο罅宀恚磕軌蛲ㄟ^面向?qū)ο蟮姆绞饺タ创龁栴}纺且,而非將對(duì)象作為一個(gè)Data
    手撕系列!能夠通過java 寫一些好玩的內(nèi)容。比如服務(wù)器,jvm,Struts坠陈,Spring等

4:建議

大家也能看到我這里所有的內(nèi)容都是加了一個(gè)字贮匕,所以我盡自己的最大能力把這個(gè)東西分享的好玩一點(diǎn)壤追。并且也希望大家意識(shí)到,我和大家分享的內(nèi)容只是我的理解,千萬不能全信。

我希望如果你真的想和我一起增強(qiáng)自己的知識(shí)脈絡(luò),最好能做到以下幾件事情:

存疑+堅(jiān)持+廣而告之+參與感

1:存疑  任何知識(shí)傳播都是會(huì)存在差異性的赵讯。所以千萬不能全信,要有自己的主觀判斷。
但是基于28法則牙寞,大概率我聊的80%內(nèi)容你應(yīng)該是要信的缝驳。嘿嘿~~
2:堅(jiān)持  這個(gè)就不談了,一句話總結(jié),世界上最難的事情就是堅(jiān)持报账,最簡單的事情就是放棄抖剿。
3:廣而告之  我希望我分享的內(nèi)容你能夠有一個(gè)落地,筆記匣沼,博客刀脏,一定要形成一個(gè)書面的內(nèi)容。
4:參與感   千萬記得仙逻,免費(fèi)的東西是最貴的萌踱,因?yàn)楹馁M(fèi)了你的時(shí)間粉铐,所以我會(huì)努力做的更好溪胶,而
如果你也認(rèn)可這件事情桑逝,請(qǐng)一定要參與進(jìn)來拘荡,而不是作為一個(gè)旁觀者驶兜。

如果這些你都能做到唉韭,那么就和我一起并肩前行吧驾胆!??

5:.java文件的沉浮之路

接下來進(jìn)入到這次分享的主要內(nèi)容,看看小J同學(xué)在執(zhí)行過程中都經(jīng)歷了什么谁鳍!??

編寫一個(gè).java文件然后依次編譯,執(zhí)行输硝。過程如下:

5-1:編寫一個(gè).java文件

編寫一個(gè).java文件

5-2:通過javac和java指令執(zhí)行

這個(gè)運(yùn)行過程就不贅述了朵你,我們直接上圖:

java跨平臺(tái)原理

5-3:揭秘第一部分.java文件如何變?yōu)?class文件

編譯器遵守什么規(guī)則俘种,將.java文件編譯為.class文件

5-3-1:編譯規(guī)則:

編譯過程

5-3-2:詞法分析:

.java文件編譯為.class文件時(shí),先進(jìn)行詞法分析 如下圖:

詞法分析

總結(jié):這里著重解析.java文件編寫的第5行代碼艾船,可以將例子后的代碼理解為java中的第5行代碼。
在進(jìn)行詞法分析時(shí),會(huì)將內(nèi)容進(jìn)過線性分析,變成一張符號(hào)表角钩。符號(hào)表為上圖中的右側(cè)內(nèi)容。右側(cè)的表格內(nèi)容由三部分構(gòu)成:

1: 唯一表示 1,2,3 類似符號(hào)表中的地址編號(hào)
2: 變量名稱 比如:標(biāo)識(shí)符position,操作符號(hào) + 等等
3: 變量的值

由詞法分析我們將整個(gè).java文件中的內(nèi)容變成了一張表。接下來:

5-3-2:語法分析:

詞法分析變?yōu)橐粡埛?hào)表农渊,繼續(xù)語法分析

語法分析

總結(jié):通過形成的符號(hào)表唇辨,會(huì)生成一顆語法二叉樹摄凡。在這里有一個(gè)很有意思的東西,就是我們觀察二叉樹,發(fā)現(xiàn)符號(hào)作為了根節(jié)點(diǎn)败砂,而且+號(hào)的節(jié)點(diǎn)在*號(hào)的節(jié)點(diǎn)之上祭隔。這里解析時(shí)倒敘解析桩撮。那么為什么*號(hào)會(huì)在+號(hào)節(jié)點(diǎn)之下右钾,其實(shí)如果你要定義一個(gè)語言時(shí)邢羔,一定要告知這個(gè)語言一定是一個(gè)形式化的,這個(gè)形式化的方式可以通過BNF定義败许。在形式化的定義規(guī)則里王带,*號(hào)的優(yōu)先級(jí)別高于+號(hào)。

`BNF`巴科斯范式(BNF: Backus-Naur Form 的縮寫)市殷。引入一種形式化符號(hào)來描述給定語言的
語法愕撰。就是通過BNF來定義語言的語法,按照定義的規(guī)則去形成編譯時(shí)的語法分析醋寝。
    擴(kuò)展:
        在雙引號(hào)中的字("word")代表著這些字符本身搞挣。而double_quote用來代表雙引號(hào)。
        在雙引號(hào)外的字(有可能有下劃線)代表著語法部分音羞。
        尖括號(hào)( < > )內(nèi)包含的為必選項(xiàng)囱桨。
        方括號(hào)( [ ] )內(nèi)包含的為可選項(xiàng)。
        大括號(hào)( { } )內(nèi)包含的為可重復(fù)0至無數(shù)次的項(xiàng)黄选。
        豎線( | )表示在其左右兩邊任選一項(xiàng)蝇摸,相當(dāng)于"OR"的意思。
        ::= 是“被定義為”的意思办陷。
這部分內(nèi)容主要涉及編譯原理,有興趣可以自行參考:

參考博文

5-3-3:java的bnf定義:

java的bnf定義

總結(jié):大家可以根據(jù)上面的bnf擴(kuò)展語法律歼,我們發(fā)現(xiàn)java的bnf定義如果要聲明一個(gè)類class_declaration被這樣定義:<modifier> 需要編寫一個(gè)修飾符民镜,修飾符的定義:modifier:=="public"|"private"...,這里我們可知定義類的時(shí)候必須時(shí)這些關(guān)鍵詞,關(guān)鍵詞已經(jīng)給出來了险毁。如果你寫的class的修飾符不是modifier定義的詞制圈,那么編譯時(shí)語法就會(huì)報(bào)錯(cuò)。依次類推畔况。“class”是必須要寫的鲸鹦,同理如果定義類是不寫則編譯語法報(bào)錯(cuò)。在到后面的identifier跷跪,也是有對(duì)應(yīng)定義的值:identifier:=="a..z,$,_"<"...." 馋嗜。其實(shí)這個(gè)不就是java規(guī)范中對(duì)于標(biāo)識(shí)符的定義嗎?不能以數(shù)字開頭吵瞻。其實(shí)要編寫一門語言葛菇。必須要有形式化的bnf定義甘磨。

5-3-4:語義分析:

語義分析,注意計(jì)算機(jī)的語義分析一定要知道眯停,計(jì)算機(jī)語言不能存在二意性济舆。這個(gè)和自然語言不通。

語義分析

總結(jié):在語義分析是會(huì)做類型檢查莺债,控制流檢查滋觉,類型檢查等等。我們回想之前的java程序齐邦,在進(jìn)行*發(fā)運(yùn)算時(shí)椎瘟,由于rate時(shí)float類型,而60時(shí)一個(gè)int類型的字面值侄旬。此時(shí)會(huì)將60這個(gè)int類型轉(zhuǎn)換為float肺蔚,其實(shí)類型轉(zhuǎn)換是在編譯時(shí)發(fā)生的±芨幔回想我們編寫程序時(shí)的基本數(shù)據(jù)類型的類型轉(zhuǎn)換錯(cuò)誤宣羊,是不是發(fā)生在編譯階段呢?

5-3-5:中間代碼生成汰蜘,優(yōu)化以及生產(chǎn)對(duì)應(yīng)的目標(biāo)文件:

產(chǎn)生最后的目標(biāo)文件

中間代碼生成仇冯,優(yōu)化以及生產(chǎn)對(duì)應(yīng)的目標(biāo)文件
中間代碼生成,優(yōu)化以及生產(chǎn)對(duì)應(yīng)的目標(biāo)文件

總結(jié):經(jīng)過語義分析的語法二叉樹開始準(zhǔn)備生產(chǎn)對(duì)應(yīng)的中間代碼族操。這里我們發(fā)現(xiàn)第一行代碼:temp1=int_to_float(60),注意苛坚,這里的語法二叉樹相當(dāng)于只是在二叉樹上給了一個(gè)標(biāo)示,說明60需要做類型轉(zhuǎn)換色难。而將60轉(zhuǎn)換為float這個(gè)是在生成中間代碼中得到實(shí)際體現(xiàn)的泼舱。第二行代碼temp2=id3*temp1,id3是什么意思呢?如果你還記得符號(hào)表的組成部分枷莉,那么這個(gè)應(yīng)該不能猜出來娇昙。它就是符號(hào)表中的唯一表示。id為3的符號(hào)表笤妙,id為3的符號(hào)表中的變量為rate冒掌,對(duì)應(yīng)的值為3.1。然后繼續(xù)操作蹲盘,直到中間代碼生成結(jié)束股毫。
我們發(fā)現(xiàn)中間的代碼有一些代碼是不需要做的,這里做代碼優(yōu)化召衔。將一部分不需要的代碼省略铃诬。
最后生成目標(biāo)的代碼,這里因?yàn)榻貓D不是java代碼,所以最后顯示的目標(biāo)文件是一個(gè)匯編指令氧急。movl id3 R2颗胡,意思就是將id3的值也就是rate中的值存儲(chǔ)到寄存器R2中,MUL #60.0吩坝,R2毒姨,意思就是將60.0和R
2寄存器中的值進(jìn)行相乘,將結(jié)果存放到R2寄存器钉寝。依次類推弧呐。movl R1,id1,意思將R1寄存器中的值存儲(chǔ)到id1中嵌纲,id1其實(shí)就是變量position俘枫,值為R1寄存器的值。

到此逮走,我們的.class文件也就生成了鸠蚪。

5-4:揭秘第二部分.class文件如何被java指令開始解析執(zhí)行的。

5-4-1:操作系統(tǒng)執(zhí)行可執(zhí)行程序师溅,調(diào)度計(jì)算機(jī)

5-4-1-1:計(jì)算機(jī)結(jié)構(gòu):
中間代碼生成茅信,優(yōu)化以及生產(chǎn)對(duì)應(yīng)的目標(biāo)文件
中間代碼生成,優(yōu)化以及生產(chǎn)對(duì)應(yīng)的目標(biāo)文件

總結(jié):

1:我們編寫的一個(gè)不論是.java文件編譯也好墓臭,解釋執(zhí)行也罷蘸鲸。首先都是存儲(chǔ)到磁盤上的。
2:我們通過鍵盤輸入javac窿锉,開始執(zhí)行編譯指令酌摇。
3:javac指令被操作系統(tǒng)讀取,然后操作系統(tǒng)調(diào)度計(jì)算機(jī)嗡载,計(jì)算機(jī)中的io總線識(shí)別到本次調(diào)度指令窑多,
然后通過io橋通知cpu,cpu將磁盤上的.java文件通過io橋鏈接io總線鼻疮,將磁盤數(shù)據(jù)讀取到主存當(dāng)中怯伊。
4:然后.java文件準(zhǔn)備開始編譯。主存中的數(shù)據(jù)會(huì)被讀取到cpu中的高速緩沖設(shè)備中判沟,進(jìn)行編譯。
5:編譯之后的.class文件崭篡,通過io橋鏈接io總線挪哄,被寫出到磁盤。
6:如果編譯時(shí)有語法錯(cuò)誤琉闪,那么cpu通過io橋迹炼,鏈接io總線上的圖形適配器,顯示報(bào)錯(cuò)信息

當(dāng)然這里鏈接以及調(diào)度的方式如果深究還是挺復(fù)雜的,暫時(shí)我們不做討論斯入,簡單點(diǎn)就是"連找發(fā)"三元素理論砂碉。如果你不是本專業(yè)的,其實(shí)目前來講這個(gè)對(duì)于我們不太重要刻两,后續(xù)老薛會(huì)稍微展開再聊聊增蹭。當(dāng)然,也可以參考下面的博文:參考博文地址磅摹。

這里之所以采用IO總線的方式鏈接各個(gè)設(shè)備滋迈,原因是很方便我可以刪除,增加設(shè)備户誓,你如果使用輻射式鏈接饼灿,就要主機(jī)連接各個(gè)設(shè)備,每個(gè)設(shè)備都有一套自己的控制線路帝美,很麻煩碍彭。我們可以不防將總線理解為一個(gè)鏈表,而輻射式理解為數(shù)組悼潭。并且總線很清晰能夠規(guī)劃出各個(gè)設(shè)備之間的關(guān)系庇忌,但是輻射的話,設(shè)備的相連關(guān)系會(huì)很復(fù)雜女责。

5-4-1-2:計(jì)算機(jī)結(jié)構(gòu)遺留問題:

總結(jié):計(jì)算機(jī)的產(chǎn)生是基于圖靈計(jì)算模型漆枚,而根據(jù)數(shù)據(jù)和指令集存放位置的不同分為了:芬諾依曼結(jié)構(gòu),哈弗結(jié)構(gòu)。有興趣大家可以稍微展開看看抵知,老薛后續(xù)會(huì)展開來聊這兩個(gè)東西墙基。

5-4-2:.class文件如何執(zhí)行

注意:jvm的加載過程不是本次分享的內(nèi)容,老薛后續(xù)會(huì)展開聊刷喜,我們這次主要聊的點(diǎn)是残制,為什么jvm虛擬機(jī)可以去執(zhí)行.class文件,這個(gè)文件中到底有什么東西掖疮?

執(zhí)行過程

總結(jié):在整個(gè)執(zhí)行過程中初茶,我們發(fā)現(xiàn)一個(gè)程序編譯為字節(jié)碼文件之后,其實(shí)就是一大堆的二進(jìn)制數(shù)據(jù)浊闪。這里字節(jié)碼展示是通過16進(jìn)制查看的恼布。然后進(jìn)過jvm加載,解析搁宾,在jvm中構(gòu)建一個(gè)運(yùn)行時(shí)結(jié)構(gòu)折汞,然后開始執(zhí)行。我們接下來就編寫程序盖腿,以及通過反匯編指令去深究一下.class文件中到底有哪些內(nèi)容爽待。

5-4-2-1:將我們之前編寫的Demo.java編譯之后進(jìn)行讀人鹜:

注意:通過流的方式將Demo.class讀取進(jìn)來,且按照16進(jìn)制顯示數(shù)據(jù)如下

讀取16進(jìn)制內(nèi)容
讀取16進(jìn)制內(nèi)容

下圖是16進(jìn)制對(duì)應(yīng)一覽表

16進(jìn)制對(duì)應(yīng)一覽表
16進(jìn)制對(duì)應(yīng)一覽表

總結(jié):

1: u:代表無符號(hào)位鸟款,u4代表無符號(hào)4個(gè)字節(jié)用來代表魔數(shù)膏燃。意思憑什么能夠確定當(dāng)前文件是.class呢?
由魔數(shù)確定何什。也就意味著.class文件的魔數(shù)為`cafebabe`,俗稱`咖啡寶貝`组哩。你也可以讀取一下
jpg或者其他類型的文件的前4個(gè)字節(jié)是什么。
2: 后續(xù)的u2富俄,無符號(hào)位2個(gè)字節(jié)代表次版本號(hào)禁炒,那就是以為當(dāng)前次版本號(hào)為0
3: 后續(xù)的u2,無符號(hào)位2個(gè)字節(jié)代表主版本號(hào)霍比,那么這里是是00 35幕袱,也就是53,也就是jdk9.
    JDK各個(gè)版本對(duì)應(yīng)關(guān)系
    JDK 1.10= 54 JDK 1.9 = 53 JDK 1.8 = 52 JDK 1.7 = 51 JDK 1.6 = 50 
    JDK 1.5 = 49 JDK 1.4 = 48 JDK 1.3 = 47 JDK 1.2 = 46 JDK 1.1 = 45
4:擴(kuò)展一下悠瞬,這里采用的是大端模式们豌,關(guān)于大小端我之前有聊過。大家也可以參考資料再看看浅妆。
其實(shí)采用大端有個(gè)地方特別好望迎,這樣我們再解析這個(gè)16進(jìn)制內(nèi)容就稍微方便一點(diǎn),直接可以省略開頭為
0的字節(jié)凌外。
5: 后續(xù)的u2辩尊,無符號(hào)2個(gè)字節(jié)代表常量池個(gè)數(shù),注意這里的常量池和我們一般意義下的內(nèi)存中的常量池
還是有區(qū)別的康辑,這里的常量池是包括所有字面常量摄欲,比如變量,類名疮薇,方法名等等胸墙。這里是00 30,那么

也就也為者有48個(gè)常量按咒,往后數(shù)48個(gè)字節(jié)迟隅,都代表的是常量值。這里注意励七,48要加上本身常量池的個(gè)數(shù) 也會(huì)占空間智袭,也就以為著一共只有47個(gè)常量。
6: 再往后的u2掠抬,代表的是訪問標(biāo)志补履,該類的修飾符,以及是否可以使用比如多態(tài)剿另,如果可以使用那么意 味著就可以使用invokespecial,這個(gè)是java字節(jié)碼調(diào)用指令,代表可以調(diào)用私有實(shí)例方法雨女,構(gòu)造器以 及使用super調(diào)用父類的實(shí)例方法等谚攒。剩下的依次類推。
大小端資料參考

通過javap -c -v反匯編氛堕,查看內(nèi)容:
以下內(nèi)容中兩個(gè)`中間的內(nèi)容是老薛寫的注釋

Classfile /Users/iongst/Desktop/Demo.class  `class文件所在地址`
  Last modified 2018年9月8日; size 884 bytes `最后一次修改時(shí)間以及大小`
  MD5 checksum 8619092419ab6d93efe90de9a29f5e36 `md5值`
  Compiled from "Demo.java" `編譯自那個(gè)文件`
public class Demo   `類的聲明`
  minor version: 0  `次版本號(hào)`
  major version: 53 `主版本號(hào) jdk9`
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER `訪問標(biāo)志馏臭,acc_public 代表是public修飾,acc_super 代表可以使用invokespecial `
  this_class: #7                          // Demo `thisclass thisclass指向了#7的地址讼稚,可以看看#7是什么`
  super_class: #8                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 3 `對(duì)照進(jìn)制一覽表括儒,分別代表接口個(gè)數(shù)為0,沒有實(shí)現(xiàn)接口
  fields字段個(gè)數(shù)為0 方法個(gè)數(shù)2個(gè)锐想,屬性有3個(gè)帮寻。問題2:這里的fields和attributes代表什么含義?`
Constant pool:      `常量池`
   #1 = Methodref          #8.#17         // java/lang/Object."<init>":()V
   #2 = Float              3.1f
   #3 = Float              60.0f
   #4 = Fieldref           #18.#19        // java/lang/System.out:Ljava/io/PrintStream;
   #5 = InvokeDynamic      #0:#23         // #0:makeConcatWithConstants:(F)Ljava/lang/String;
   #6 = Methodref          #24.#25        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #7 = Class              #26            // Deme `存儲(chǔ)了#26 繼續(xù)往下找`
   #8 = Class              #27            // java/lang/Object
   #9 = Utf8               <init>
  #10 = Utf8               ()V
  #11 = Utf8               Code
  #12 = Utf8               LineNumberTable
  #13 = Utf8               main
  #14 = Utf8               ([Ljava/lang/String;)V
  #15 = Utf8               SourceFile
  #16 = Utf8               Demo.java
  #17 = NameAndType        #9:#10         // "<init>":()V
  #18 = Class              #28            // java/lang/System
  #19 = NameAndType        #29:#30        // out:Ljava/io/PrintStream;
  #20 = Utf8               BootstrapMethods
  #21 = MethodHandle       6:#31          // REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
  #22 = String             #32            // 計(jì)算結(jié)果是:\u0001
  #23 = NameAndType        #33:#34        // makeConcatWithConstants:(F)Ljava/lang/String;
  #24 = Class              #35            // java/io/PrintStream
  #25 = NameAndType        #36:#37        // println:(Ljava/lang/String;)V
  #26 = Utf8               Demo         `就存儲(chǔ)了類名赠摇,問題1:為什么要存儲(chǔ)類名固逗?`
  #27 = Utf8               java/lang/Object
  #28 = Utf8               java/lang/System
  #29 = Utf8               out
  #30 = Utf8               Ljava/io/PrintStream;
  #31 = Methodref          #38.#39        // java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
  #32 = Utf8               計(jì)算結(jié)果是:\u0001
  #33 = Utf8               makeConcatWithConstants
  #34 = Utf8               (F)Ljava/lang/String;
  #35 = Utf8               java/io/PrintStream
  #36 = Utf8               println
  #37 = Utf8               (Ljava/lang/String;)V
  #38 = Class              #40            // java/lang/invoke/StringConcatFactory
  #39 = NameAndType        #33:#44        // makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
  #40 = Utf8               java/lang/invoke/StringConcatFactory
  #41 = Class              #46            // java/lang/invoke/MethodHandles$Lookup
  #42 = Utf8               Lookup
  #43 = Utf8               InnerClasses
  #44 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
  #45 = Class              #47            // java/lang/invoke/MethodHandles
  #46 = Utf8               java/lang/invoke/MethodHandles$Lookup
  #47 = Utf8               java/lang/invoke/MethodHandles
  `常量池個(gè)數(shù)一共有47個(gè),所以雖然我們查看是48個(gè)是包含本身常量池的1的所以是48`
{
  public Demo();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 1: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=4, args_size=1
         0: bipush        10
         2: istore_1
         3: ldc           #2                  // float 3.1f
         5: fstore_2
         6: iload_1
         7: i2f
         8: fload_2
         9: ldc           #3                  // float 60.0f
        11: fmul
        12: fadd
        13: fstore_3
        14: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
        17: fload_3
        18: invokedynamic #5,  0              // InvokeDynamic #0:makeConcatWithConstants:(F)Ljava/lang/String;
        23: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        26: return
      LineNumberTable:
        line 3: 0
        line 4: 3
        line 5: 6
        line 6: 14
        line 7: 26
}
SourceFile: "Demo.java"
InnerClasses:
  public static final #42= #41 of #45;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
  0: #21 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #22 計(jì)算結(jié)果是:\u0001

文末總結(jié):

大家如果真的能耐著性子把這個(gè)文章看完藕帜,在我看來真的很厲害了烫罩。后面也埋了一些坑,比如后面的方法調(diào)用洽故,我這里一共添加了108號(hào)反編譯之后的代碼贝攒,后面很多代碼老薛也沒有講解,這個(gè)作為后續(xù)內(nèi)容时甚。那么我們是不是可以這樣理解隘弊,如果我們將一個(gè).class文件讀取進(jìn)來之后,按照對(duì)照一覽表開始解析撞秋,只要我們能夠分析出來運(yùn)行時(shí)數(shù)據(jù)區(qū)长捧,我們完全是可以自己寫一個(gè)jvm的。這是沒有問題哦吻贿。

如果大家有什么問題串结,大家可以在文末或者是微信私聊老薛。老薛微信 lukun0402

本章內(nèi)容參考書籍資料:《編譯原理》 《深入理解計(jì)算機(jī)系統(tǒng)》 《碼農(nóng)翻身》

課后作業(yè):

  • 我們知道cpu是個(gè)快速設(shè)備舅列,內(nèi)存稍次之肌割,磁盤排第三,如果你走網(wǎng)絡(luò)會(huì)更慢帐要,那么整個(gè)執(zhí)行過程其實(shí)是通過最低速設(shè)備決定的把敞,你有什么比較好的辦法能夠解決這個(gè)問題嗎?
  • 給大家布置了數(shù)據(jù)結(jié)構(gòu)的系統(tǒng)榨惠,如果興趣的同學(xué)可以做一做奋早。作業(yè)地址盛霎。也可以復(fù)制鏈接:https://github.com/iongst/dataStructure
  • 在作業(yè)中也留了一些作業(yè),編寫數(shù)據(jù)結(jié)構(gòu)時(shí)耽装,在老薛寫的接口中愤炸,已經(jīng)留了思考的彩蛋,大家努力查找吧掉奄。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末规个,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子姓建,更是在濱河造成了極大的恐慌诞仓,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件速兔,死亡現(xiàn)場離奇詭異墅拭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)憨栽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門帜矾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屑柔,你說我怎么就攤上這事屡萤。” “怎么了掸宛?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵死陆,是天一觀的道長。 經(jīng)常有香客問我唧瘾,道長措译,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任饰序,我火速辦了婚禮领虹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘求豫。我一直安慰自己塌衰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布蝠嘉。 她就那樣靜靜地躺著最疆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚤告。 梳的紋絲不亂的頭發(fā)上努酸,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音杜恰,去河邊找鬼获诈。 笑死仍源,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烙荷。 我是一名探鬼主播镜会,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼终抽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起桶至,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤昼伴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后镣屹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體圃郊,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年女蜈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了持舆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伪窖,死狀恐怖逸寓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情覆山,我是刑警寧澤竹伸,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站簇宽,受9級(jí)特大地震影響勋篓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜魏割,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一譬嚣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钞它,春花似錦拜银、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至耻卡,卻和暖如春疯汁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卵酪。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工幌蚊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谤碳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓溢豆,卻偏偏與公主長得像蜒简,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子漩仙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理搓茬,服務(wù)發(fā)現(xiàn),斷路器队他,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 廈門的今天卷仑,整個(gè)整個(gè)的上午,傾盆大雨一直下著不停麸折。預(yù)約好朋友去辦事锡凝。結(jié)果按約定時(shí)間到達(dá),但因?yàn)橄掠晏旃柑洌\?..
    南嘯閱讀 149評(píng)論 0 0
  • 這世上每個(gè)人都不一樣窜锯,都有自己的喜怒趨惡,自己的內(nèi)心舒適區(qū)芭析,沒法統(tǒng)一锚扎,沒法規(guī)定。但一個(gè)人卻是可以為了自己喜歡的另一...
    Malcolmyz閱讀 234評(píng)論 0 0
  • 感恩凌晨一點(diǎn)實(shí)在是膽囊炎疼的實(shí)在是厲害一個(gè)人跑到醫(yī)院放刨,感恩送我的司機(jī)工秩,感恩 感謝五附院的醫(yī)生和護(hù)士對(duì)我的無微不至的...
    能量團(tuán)隊(duì)閱讀 203評(píng)論 0 0