Java代碼編譯和執(zhí)行的整個(gè)過程

一、簡(jiǎn)述

Java代碼編譯和執(zhí)行的整個(gè)過程包含了三個(gè)重要的機(jī)制:①Java源碼編譯機(jī)制;②類加載機(jī)制;③類執(zhí)行機(jī)制

二鳍怨、Java源碼編譯機(jī)制

Java代碼編譯是由Javac編譯器來完成,流程如圖:

Javac是一種編譯器跪妥,能將一種語言規(guī)范轉(zhuǎn)化成另外一種語言規(guī)范,通常編譯器都是將便于人理解的語言規(guī)范轉(zhuǎn)化成機(jī)器容易理解的語言規(guī)范声滥,如C/C++或者匯編語言都是將源代碼直接編譯成目標(biāo)機(jī)器碼眉撵,這個(gè)目標(biāo)機(jī)器代碼是CPU直接執(zhí)行的指令集合。這些指令集合也就是底層的一種語言規(guī)范落塑。

Javac的編譯器也是將Java這種對(duì)人非常友好的編程語言編譯成對(duì)所有機(jī)器都非常友好的一種語言纽疟。這種語言不是針對(duì)某種機(jī)器或某個(gè)平臺(tái)。怎么消除不同種類憾赁,不同平臺(tái)之間的差異這個(gè)任務(wù)就有JVM來完成污朽,而Javac的任務(wù)就是將Java源代碼語言轉(zhuǎn)化為JVM能夠識(shí)別的一種語言,然后由JVM將JVM語言再轉(zhuǎn)化成當(dāng)前這個(gè)機(jī)器能夠識(shí)別的機(jī)器語言龙考。

Javac的任務(wù)就是將Java源代碼編譯成Java字節(jié)碼蟆肆,也就是JVM能夠識(shí)別的二進(jìn)制代碼,從表面看是將.java文件轉(zhuǎn)化為.class文件晦款。而實(shí)際上是將Java源代碼轉(zhuǎn)化成一連串二進(jìn)制數(shù)字炎功,這些二進(jìn)制數(shù)字是有格式的,只有JVM能夠真確的識(shí)別到底代表什么意思缓溅。

編譯器把一種語言規(guī)范轉(zhuǎn)化為另一種語言規(guī)范的這個(gè)過程需要哪些步驟蛇损?參照《編譯原理》,總結(jié)過程如下:

1??詞法分析:讀取源代碼坛怪,一個(gè)字節(jié)一個(gè)字節(jié)的讀進(jìn)來淤齐,找出這些詞法中定義的語言關(guān)鍵詞如:if、else袜匿、while等更啄,識(shí)別哪些if是合法的哪些是不合法的。這個(gè)步驟就是詞法分析過程居灯。
詞法分析的結(jié)果:就是從源代碼中找出了一些規(guī)范化的token流锈死,就像人類語言中贫堰,給你一句話你要分辨出哪些是一個(gè)詞語,哪些是標(biāo)點(diǎn)符號(hào)待牵,哪些是動(dòng)詞其屏,哪些是名詞。

2??語法分析:就是對(duì)詞法分析中得到的token流進(jìn)行語法分析缨该,這一步就是檢查這些關(guān)鍵詞組合在一起是不是符合Java語言規(guī)范偎行。如if的后面是不是緊跟著一個(gè)布爾型判斷表達(dá)式。
語法分析的結(jié)果:就是形成一個(gè)符合Java語言規(guī)定的抽象語法樹贰拿,抽象語法樹是一個(gè)結(jié)構(gòu)化的語法表達(dá)形式蛤袒,它的作用是把語言的主要詞法用一個(gè)結(jié)構(gòu)化的形式組織在一起。這棵語法樹可以被后面按照新的規(guī)則再重新組織膨更。

3??語義分析:語法分析完成之后也就不存在語法問題了妙真,語義分析的主要工作就是把一些難懂的,復(fù)雜的語法轉(zhuǎn)化成更簡(jiǎn)單的語法荚守。就如難懂的文言文轉(zhuǎn)化為大家都懂的白話文珍德,或者是注釋一下一些不懂的成語。
語義分析結(jié)果:就是將復(fù)雜的語法轉(zhuǎn)化為簡(jiǎn)單的語法矗漾,對(duì)應(yīng)到Java就是將foreach轉(zhuǎn)化為for循環(huán)锈候,還有一些注釋等。最后生成一棵抽象的語法樹敞贡,這棵語法樹也就更接近目標(biāo)語言的語法規(guī)則泵琳。

4??字節(jié)碼生成:將會(huì)根據(jù)經(jīng)過注釋的抽象語法樹生成字節(jié)碼,也就是將一個(gè)數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化為另外一個(gè)數(shù)據(jù)結(jié)構(gòu)誊役。就像將所有的中文詞語翻譯成英文單詞后按照英文語法組裝文英文語句获列。代碼生成器的結(jié)果就是生成符合java虛擬機(jī)規(guī)范的字節(jié)碼。這個(gè)過程中的需要的組件如下圖:

從上面的描述中得知編譯就是將一種語言通過分析分解蛔垢,再按照一定的方式先形成一個(gè)簡(jiǎn)單的框架(將Java源文件的字節(jié)流轉(zhuǎn)化為對(duì)應(yīng)的token流)蛛倦。然后再通過詳細(xì)的分析按照一定的規(guī)定在這個(gè)框架里添加?xùn)|西使這個(gè)token流形成更加結(jié)構(gòu)化的語法樹(就是將前面生成的token流中的一個(gè)個(gè)單詞組裝成一句話),但是這棵樹離目標(biāo)———Java字節(jié)碼還有點(diǎn)差距啦桌,所以再進(jìn)行語義分析使那顆粗糙的樹更加完整完善(給類添加默認(rèn)的構(gòu)造函數(shù)溯壶,檢查變量在使用前有沒有初始化,檢查操作變量類型是否匹配)甫男,然后javac編譯器調(diào)用com.sun.tools.javac.jvm.Gen類遍歷這棵語法樹將java方法中的代碼塊轉(zhuǎn)換成符合JVM語法的命令形式的二進(jìn)制數(shù)據(jù)且改。按照J(rèn)VM的文件組織格式將字節(jié)碼輸出到以class為擴(kuò)展名的文件中,也就是生成最終的java字節(jié)碼板驳。詞法分析就是將關(guān)鍵詞組織成token流即檢查源碼中的的關(guān)鍵詞是否正確并組織成token流又跛,而語法分析就是檢查源碼是否符合java語法規(guī)范并將詞組成語句。語義分析就是簡(jiǎn)化復(fù)雜的添加缺少的若治,檢查變量類型是否合法慨蓝。代碼生成器就是遍歷這棵樹生成符合JVM規(guī)范的代碼感混。

最后生成的class文件由以下部分組成:
①結(jié)構(gòu)信息。包括class文件格式版本號(hào)及各部分的數(shù)量與大小的信息礼烈。
②元數(shù)據(jù)弧满。對(duì)應(yīng)于Java源碼中聲明與常量的信息。包含類此熬、繼承的超類庭呜、實(shí)現(xiàn)的接口的聲明信息、域與方法聲明信息和常量池犀忱。
③方法信息募谎。對(duì)應(yīng)Java源碼中語句和表達(dá)式對(duì)應(yīng)的信息。包含字節(jié)碼阴汇、異常處理器表数冬、求值棧與局部變量區(qū)大小、求值棧的類型記錄搀庶、調(diào)試符號(hào)信息拐纱。

三、類執(zhí)行機(jī)制

Java字節(jié)碼的執(zhí)行是由JVM執(zhí)行引擎來完成地来,流程圖如下:

JVM是基于棧的體系結(jié)構(gòu)來執(zhí)行class字節(jié)碼的。線程創(chuàng)建后熙掺,都會(huì)產(chǎn)生程序計(jì)數(shù)器和棧未斑,程序計(jì)數(shù)器存放下一條要執(zhí)行的指令。棧中存放一個(gè)個(gè)棧幀币绩,每個(gè)棧幀對(duì)應(yīng)著每個(gè)方法的每次調(diào)用蜡秽,而棧幀又是由局部變量區(qū)和操作數(shù)棧兩部分組成,局部變量區(qū)用于存放方法中的局部變量和參數(shù)缆镣,操作數(shù)棧中用于存放方法執(zhí)行過程中產(chǎn)生的中間結(jié)果芽突。棧的結(jié)構(gòu)如下圖:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市董瞻,隨后出現(xiàn)的幾起案子寞蚌,更是在濱河造成了極大的恐慌,老刑警劉巖钠糊,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挟秤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡抄伍,警方通過查閱死者的電腦和手機(jī)艘刚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來截珍,“玉大人攀甚,你說我怎么就攤上這事箩朴。” “怎么了秋度?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵炸庞,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我静陈,道長(zhǎng)燕雁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任鲸拥,我火速辦了婚禮拐格,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘刑赶。我一直安慰自己捏浊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布撞叨。 她就那樣靜靜地躺著金踪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪牵敷。 梳的紋絲不亂的頭發(fā)上胡岔,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音枷餐,去河邊找鬼靶瘸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛毛肋,可吹牛的內(nèi)容都是我干的怨咪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼润匙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼诗眨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起孕讳,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤匠楚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后厂财,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體油啤,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年蟀苛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了益咬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖幽告,靈堂內(nèi)的尸體忽然破棺而出梅鹦,到底是詐尸還是另有隱情,我是刑警寧澤冗锁,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布齐唆,位于F島的核電站,受9級(jí)特大地震影響冻河,放射性物質(zhì)發(fā)生泄漏箍邮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一叨叙、第九天 我趴在偏房一處隱蔽的房頂上張望锭弊。 院中可真熱鬧,春花似錦擂错、人聲如沸味滞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剑鞍。三九已至,卻和暖如春爽醋,著一層夾襖步出監(jiān)牢的瞬間蚁署,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來泰國打工蚂四, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留光戈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓证杭,卻偏偏與公主長(zhǎng)得像田度,于是被迫代替她去往敵國和親妒御。 傳聞我的和親對(duì)象是個(gè)殘疾皇子解愤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359