早期(編譯期)優(yōu)化
前端編譯器(把*.java文件轉(zhuǎn)變成*.class文件):Sun的Javac掌眠、 Eclipse JDT中的增量式編譯器(ECJ)蕾盯。
JIT編譯器(把字節(jié)碼轉(zhuǎn)變成機器碼):HotSpot VM的C1、 C2編譯器蓝丙。
AOT編譯器(把*.java文件編譯成本地機器代碼):GNU Compiler for the Java(GCJ)级遭、 Excelsior JET望拖。
Javac編譯器
編譯過程大致分為三個:解析與填充符號表過程、插入式注解處理器的注解處理過程挫鸽、分析與字節(jié)碼生成過程说敏。
- 解析與填充符號表過程
- 1.詞法、 語法分析
- 詞法分析是將源代碼的字符流轉(zhuǎn)變?yōu)闃擞洠═oken)集合
-
語法分析是根據(jù)Token序列構(gòu)造抽象語法樹的過程丢郊,抽象語法樹(Abstract Syntax Tree,AST)是一種用來描述程序代碼語法結(jié)構(gòu)的樹形表示方式盔沫,語法樹的每一個節(jié)點都代表著程序代碼中的一個語法結(jié)構(gòu)(Construct)
- 2.填充符號表
- 符號表(Symbol Table)是由一組符號地址和符號信息構(gòu)成的表格
- 1.詞法、 語法分析
- 注解處理器
- 如果插入式注解處理器在處理注解期間對語法樹進行了修改,編譯器將回到解析及填充符號表的過程重新處理枫匾,直到所有插入式注解處理器都沒有再對語法樹進行修改為止架诞,如圖1的回環(huán)過程(Round)。
- 語義分析與字節(jié)碼生成
- 語義分析的主要任務(wù)是對結(jié)構(gòu)上正確的源程序進行上下文有關(guān)性質(zhì)的審查婿牍,如進行類型檢查侈贷。
- 語義分析過程分為標注檢查以及數(shù)據(jù)及控制流分析
- 1.標注檢查
- 檢查的內(nèi)容包括諸如變量使用前是否已被聲明、 變量與賦值之間的數(shù)據(jù)類型是否能夠匹配等
- 2.數(shù)據(jù)及控制流分析
- 對程序上下文邏輯更進一步的驗證等脂,它可以檢查出諸如程序局部變量在使用前是否有賦值俏蛮、 方法的每條路徑是否都有返回值、 是否所有的受查異常都被正確處理了等問題上遥。
- 1.標注檢查
- 局部變量與字段(實例變量搏屑、 類變量)是有區(qū)別的,它在常量池中沒有
CONSTANT_Fieldref_info的符號引用粉楚,自然就沒有訪問標志(Access_Flags)的信息辣恋,甚至可能連名稱都不會保留下來(取決于編譯時的選項),自然在Class文件中不可能知道一個局部變量是不是聲明為final- 3.解語法糖
- 語法糖指指在計算機語言中添加的某種語法模软,這種語法對語言的功能并沒有影響伟骨,但是更方便程序員使用。
- 虛擬機運行時不支持泛型燃异、變長參數(shù)等語法携狭,它們在編譯階段還原回簡單的基礎(chǔ)語法結(jié)構(gòu),這個過程稱為解語法糖回俐。
- 4.字節(jié)碼生成
- 字節(jié)碼生成階段不僅僅是把前面各個步驟所生成的信息(語法樹逛腿、 符號表)轉(zhuǎn)化成字節(jié)碼寫到磁盤中,編譯器還進行了少量的代碼添加和轉(zhuǎn)換工作仅颇。
- 實例構(gòu)造器<init>()方法和類構(gòu)造器<clinit>()方法就是在這個階段添加到語法樹之中的
- 3.解語法糖
Java語法糖
泛型與類型擦除
泛型技術(shù)實際上是Java語言的一顆語法糖单默,Java語言中的泛型實現(xiàn)方法稱為類型擦除,基于這種方法實現(xiàn)的泛型稱為偽泛型忘瓦。