本文講述一個.java源文件是如何通過javac編譯器的一系列操做變爲.class文件的.前端
說到編譯,你們都能想到是編譯器通過一系列方法將源代碼轉變爲目標機器代碼,但Java做爲一個平臺無關性語言,前端編譯的主要做用是將源代碼轉變爲JVM能識別出的語言,而具體與機器相關的機器代碼生成由後續JVM本身掌控.java
Java中的編譯分爲前端編譯和後端編譯兩種,本文講解的主要是前端編譯,後端編譯是JVM運行期的時候將Java代碼編譯爲本地機器碼的過程,由於Java是一門動態性語言,大部分的代碼優化都是放在後端編譯中,展開來說篇幅比較長,所以具體的優化方式放在後續文章再詳細描述.程序員
如上文所說,javac編譯器能作到將一門高級語言轉變爲JVM能識別出的語言,而若要完成這些功能須要javac擁有哪些模塊和功能,下面就由筆者來爲你們講解一下.web
ps:因筆者對彙編語言也不甚瞭解,因此講述的編譯細節也不是十分具體,此外如有錯誤,請你們積極指出,謝謝!後端
詞法分析的做用是將源代碼一個一個字節的讀取出來,識別出哪些字節是Java語言中的關鍵字,如if,while,for等,哪些是程序員自定義字節,如a,b等.舉例來講,Java中的一句jvm
int a = b + 1;
句中就包含了 int , a , = , b , + , 1 , ;七個字節.學習
語法分析的做用是對上一步獲得的Token字節流進行分析,驗證其是否符合Java語言規範,如在int後面是否緊跟着一個符合Java命名規範的變量名.=前的變量是否可賦值等等.優化
在這一步會獲得一個語法樹,其功能是將語言的主要詞法用一個結構化的形式組織在一塊兒.code
在上一步獲得了一個語法樹,但其沒法保證這個語法樹是邏輯正確的,例如coder可能會爲一個尚未聲明的變量賦值,這個錯誤在前兩步是沒法檢查出的,只有在這一步經過語義分析才能檢查出錯誤.另外在這一步還會對語法糖進行解糖(desugar)操做,將複雜難懂的語法轉變爲簡單易懂的語法.blog
具體Java中有哪些語法糖,每一個語法糖對應的基礎結構留待下篇文章再詳細講解.
語法糖:計算機語言中添加的某種語法,這種語法對語言的功能並無影響,可是更方便程序員使用。一般來講使用語法糖可以增長程序的可讀性,從而減小程序代碼出錯的機會。(來自百度百科)
例如Java中的自動拆裝箱,foreach循環等都屬於語法糖的範疇.
字節碼生成是javac編譯過程的最後一個階段.其做用是將前面各個步驟生成的信息轉化爲字節碼寫到磁盤中,生成.class文件,也宣佈了整個編譯過程的結束.
本文主要描述Java中的前端編譯,敘述了Java源代碼是如何通過 詞法分析,語法分析,語義分析,字節碼生成 4個步驟變爲.class文件的.具體的實現細節,筆者因對彙編不是十分了解,且認爲不是十分重要而沒有具體展開,若讀者有興趣,能夠自行翻閱< <深刻理解java虛擬機> >進行學習.
文章在公衆號"iceWang"第一手更新,有興趣的朋友能夠關注公衆號,第一時間看到筆者分享的各項知識點,謝謝!筆芯.
本系列文章主要借鑑自 <深刻分析javaweb技術內幕> 和 <深刻理解java虛擬機-jvm高級特性與最佳實踐> .