我們寫的Java程序是遵循着Java的語言規範,是面向開發者能讀懂的語言。但機器不是人,它不能懂“System.out.println("hello world");”是什麼意思。你想讓cpu爲你做事,那你就必須說cpu能聽得懂的話,而cpu能聽得懂的話就是一個一個的指令。所以你寫的Java代碼會被先編譯成.class文件也就是JVM能讀懂的語言,再由ClassLoader將.class文件加載到JVM運行時數據區,並最終由JVM翻譯、調用C/C++執行。
我們就先從.Java到.class的編譯過程說起。
首先要讀取源代碼,一個字節一個字節地讀進來,找到關鍵詞如if、for、while等,這就是詞法分析的過程。這個過程結束以後Java代碼就變成了規範的Token流,就像我們把一句話中的名詞、動詞、標點符號分辨出來。
接着就是對Token流進行語法分析了,比如If後面跟着的是不是一個布爾型的變量,並將符合規範的語法使用語法樹存貯起來。之所以要用語法樹來存儲,是因爲這樣做可以方便以後對這棵樹按照新的規則重新組織,這也是編譯器的關鍵所在。
接下來就是語義分析,編譯器可以保證形成語法樹以後不存在語法錯誤,但語義是否正確則無法保證。還有就是Java會有一些相對複雜的語法,語義分析器的作用就是將這些複雜的語法翻譯成更簡單的語法,比如將foreach翻譯成簡單的for循環,使它更接近目標語言的語法規則。
最後就是由代碼生成器將將語義分析的結果生成符合Java虛擬機規範的字節碼了。
所以Java代碼變成.class文件所經過的主要步驟有:
1.詞法分析器 --->Token流
2.語法分析器 --->語法樹
3.語義分析器 --->更加符合目標代碼的語法樹
4.代碼生成器 --->生成.class