Java早期(編譯期)優化

Java早期(編譯期)優化

1. Javac編譯器

1.1 編譯步驟

編譯過程可分爲3個步驟:java

  1. 解析與填充符號過程
  2. 插入式註解處理器的註解處理過程
  3. 分析與字節碼生成過程

1.2 解析與填充符號表

解析步驟包含了詞法分析和語法分析兩個過程。程序員

1.2.1 詞法、語法分析

詞法分析是將源代碼的字符流轉變爲標記(Token)集合,標記是編譯過程的最小元素。 語法分析是根據Token序列構建抽象語法樹的過程。 抽象語法樹是一種用來描述程序代碼語法結構的樹形表示方式,語法樹中的每個節點都表明着程序代碼中的一個語法結構,例如包、類型、修飾符、運算符、接口等。優化

1.2.2 填充符號表

符號表是由一組符號地址和符號信息構成的表格。符號表中登記的信息在編譯的不一樣階段都要用到。在語義分析中,符號表所登記的內容將用於語義檢查和產生中間代碼。在目標代碼生成階段,當對符號名進行地址分配時,符號表是地址分配的依據。插件

1.3 註解處理器

JDK1.6之中提供了一組插入式註解處理器的標準API在編譯期間對註解進行處理,能夠把它看作是一組編譯器插件,在這些插件中,能夠讀取、修改、添加抽象語法樹中的任意元素。若這些插件在處理註解期間對語法樹進行了修改,編譯器將回到解析及填充符號表的過程從新處理,直到全部插入式註解處理器都沒有再對語法樹進行修改成止,每一次循環稱爲一個Round。code

1.4 語義分析與字節碼生成

語法樹能表示一個結構正確的源程序的抽象,但沒法保證資源程序是符合邏輯的。而語義分析的主要任務是對結構上正確的源程序進行上下文有關性質的審查,如類型審查。接口

1.4.1 標註檢查

在Javac的編譯過程當中,語義分析過程分爲標註檢查以及數據及控制流分析兩個步驟。 標註檢查步驟檢查的內容包括諸如變量使用前是否已被聲明、變量與賦值之間的數據類型是否可以匹配等。 在標註檢查步驟中,還有一個重要的動做稱爲變量摺疊。例如: 在代碼中寫下:資源

int a = 1 + 2;

在通過變量摺疊以後,1 + 2會被摺疊爲字面量3。因此在代碼裏定義int a = 1 + 2比起直接定義int a = 3並不會增長程序運行期的運算量。編譯器

1.4.2 數據及控制流分析

數據及控制流分析是對程序上下文邏輯更進一步的驗證,他能夠檢查出諸如程序局部變量在使用前是否有賦值、方法的每條路徑是否都有返回值、是否全部的受檢查異常都被正確處理了等問題。it

1.4.3 解語法糖

語法糖(Syntactic Sugar),也稱糖衣語法,由英國計算機科學家Peter J.Landin發明的一個術語,指在計算機語言中添加的某種語法,這種語法對語言的功能並無影響,可是更方便程序員使用。 Java中的語法糖會在編譯階段還原回簡單的基礎語法結構,這個過程成爲解語法糖編譯

1.4.4 字節碼生成

字節碼生成是Javac編譯過程的最後一個階段,此階段編譯器還進行了少許的代碼添加和轉換工做。實例構造器<init>()和類構造器<clinit>()就是在這個階段添加到語法樹中的。完成了對語法樹的遍歷和調整以後,生成最終的Class文件。

2. Java語法糖的味道

2.1 泛型與類型擦除

泛型的本質是參數化類型,即所所操做的數據類型被指定爲一個參數。這種參數類型能夠應用在類、接口和方法的建立中,分別被稱爲泛型類、泛型接口和泛型方法。 Java中泛型只存在於源代碼中,在編譯階段會擦除泛型,替換爲原來的原生類型(Raw Type,也稱裸類型),並在相應地方插入強制轉型代碼。

2.2 自動裝箱、拆箱與遍歷循環

包裝類的「==」運算在不遇到算術運算的狀況下不會自動拆箱,它們的equals()方法不處理數據轉型

相關文章
相關標籤/搜索