1. 程式人生 > >class文件的編譯過程

class文件的編譯過程

語法 代碼 程序 常用 目的 標記 nbsp 所有 構造器

編譯器主要分為3類:前端編譯器、JIT編譯器、AOT編譯器

前端編譯器:把*.Java文件轉變成*.class文件——Sun的Javac

JIT編譯器:就是即時編譯器,將class文件轉變成機器碼的過程——HotSpotVM的C1、C2

AOT編譯器:直接把*.java文件編譯成本地代碼的過程——Excelsior JET

Javacde 編譯過程主要分為以下3種

①解析與填充符號的過程

1.詞法、語法分析

詞法分析是將源代碼的字符流轉變為標記集合(單個字符是程序編寫過程的最小元素、而標記則是編譯過程的最小元素,關鍵字、變量名、字面量都可以成為標記)

如int a=b+2;包含了6個標記

語法分析是根據標記序列構造抽象語法樹的過程(語法樹的每一個節點都代表著程序序列中的一個語法結構,如包、類型、修飾符)

2.填充符號表

符號表是由一組符號地址和符號信息構成的表格,可以將符號表想象成哈希表中K-V值對的形式(實際上不一定是哈希表的信息,可以是有序符號表、樹狀符號表、棧結構符號表等)

在語義分析中,符號表所登記的內容將用於語義檢查和產生中間代碼

在目標代碼生成階段,當對符號名進行地址分配時,符號表是地址分配的依據

②插入式註解處理器的註解處理過程

在JDK1.6中,提供了一組插入式註解處理器的標準API在編期間對註解進行處理,可以將它看作是編譯器的插件,這些插件可以讀取、修改、添加抽象語法樹中的任意元素。當這些插件在註解處理期間對語法樹進行修改,編譯器將回到解析及填充符號表的過程重新處理,直到所有的插入式註解處理器都沒有再對語法樹進行修改為止。

③分析與字節碼生成過程

語義分析的主要任務:對結構上正確的源程序進行上下文有關性質的審查,如進行類型審查。

1.標註檢查

標註檢查:檢查的內容包括變量使用前是否已被聲明、變量與賦值之間的數據類型是否匹配等,其中一個重要的動作稱為常量折疊,如int a=1+1,折疊之後就變為int a=2.

2.數據及控制流分析

數據及控制流分析是對程序上下文邏輯更進一步的驗證,他可以檢驗出諸如程序局部變量在使用前是否有賦值、方法的每條路徑是否都有返回值、是否所有的受檢查異常都被正確處理了等問題。編譯期間的數據及控制流分析與類加載時的數據及控制流分析的目的基本一致,但校驗範圍有所區別,有一些校驗項只有在編譯期或運行期才能運行。如將局部變量聲明為final,對運行期是沒有影響的,變量的不變性僅僅由編譯器在編譯期間保證。

3.解語法糖

Java中最常用的語法糖主要是:泛型、變長參數、自動裝箱和拆箱等,在編譯階段還原回簡單的基礎語法結構,該過程稱為解語法糖

4.字節碼生成

字節碼生成階段不僅僅把前面各個步驟所生成的信息(語法樹、符合表)轉化成字節碼寫到磁盤中去,編譯器還添加了少量的代碼和轉換工作。如實例構造器<init>()方法和<clinit>()方法,就是在該過程添加到語法樹之中。完成語法樹的遍歷和調整後,就會把填充了所有的符號交給ClassWrite類,生成字節碼。

class文件的編譯過程