Java編譯器總的來講分爲前端編譯器,JIT(just in time compiler)編譯器,AOT(Ahead Of Time Compiler)編譯器三種。 前端
- 前端編譯器: 將Java文件編譯爲class文件的編譯器,目前主要有如下兩個,Sun提供的Javac 和Eclipse JDT中的增量式編譯器(ECJ)
- JIT編譯器: 虛擬機後端運行期編譯器,把字節碼轉換爲機器碼的過程。HotSpot Vm中提供的C1, C2編譯器
- AOT編譯器:直接把Java文件轉換爲本地機器碼的過程。 GNU Compiler for the java(GCJ), Excelsior JET
* 在Java 3 之後爲了使其餘不經過Javac編譯的其餘在java虛擬機上執行的語言能夠享受到編譯器優化所帶來的好處因此,java把全部的編譯器優化工做都放到了後端及時編譯器中。 java
Sun Javac編譯器 後端
Sun javac編譯器編譯過程分爲三個步驟,解析填充符號表,插入式註解處理器的註解處理過程,分析與字節碼生產過程 優化
**Javac編譯器的入口是com.sun.tools.javac.main.JavaCompiler類,主要邏輯集中在compile和compile2方法中 spa
- 解析填充符號表
詞法分析:將源代碼的字符流轉變爲標記(Token)集合 com.sun.tools.javac.parser.Scanner類進行詞法分析
語法分析:用標記序列構造抽象語法樹(AST,Abstract Syntax Tree)。Eclipse AST View插件能夠用來查看抽象語法樹
- 註解處理器
Java1.5以後提供了對註解(Annotations)的支持,註解處理器能夠理解爲抽象語法樹的一組插件,這些插件能夠對抽象語法樹直接進行讀取,修改,添加操做。
若是在解析註解期間,對語法樹進行了修改,那麼編譯器回到解析及填充符號表的過程從新處理,直到全部的插入式註解處理器沒有對語法樹進行修改成止。
JavacCompiler 類中initProcessAnnotations()方法對註解處理器進行初始化,JavacProcessingEnvironment類的doProcessing()方法生成新的JavacCompiler對編譯的後續過程進行處理。
- 語義分析與字節碼生成
語法分析以後編譯器獲得程序的抽象語法樹表示,語法樹表示一個結構正確的源程序抽象,但沒法保證源程序是符合邏輯的,語義分析就是對結構正確的源程序上下文進行審查。
語法分析與字節碼生成總共分爲,標註檢查,數據及控制流分析,解語法糖,字節碼生成四個過程。
標註檢查,和數據及控制流分析主要是對程序上下文環境進行分析檢查。 解語法糖:在Java中經常使用到的解語法糖就是泛型,在Java虛擬機是不支持泛型的。只是經過語法糖進行語法擴展。