Javac的實現過程

主要介紹Javac的實現過程及原理。java

首先弄明白什麼是Javac?jvm

Javac是一種編譯器,將一種語言轉換爲另外一種語言規範。編譯器的做用就是將符合java語言規範的源代碼轉化爲JVM虛擬機可以識別的字節碼文件的過程。函數

對於java而言。javac任務就是將java源代碼轉換爲jvm可以識別的二進制碼。將.java文件轉換爲.class文件,這些.class文件也就是字節碼文件只有JVM可以識別。spa

 

 

 

編譯過程的原理:對象

一、詞法分析:首先將源代碼按照字節的方式讀取,而後找出定義的語法關鍵字(if/else/for等),而後判斷哪些關鍵字是符合java語言規範的,通過整理分析返回一些規範化的Token流blog

二、語法分析:對Token流進行分析。分析出這些關鍵字組合在一塊兒是否符合java語言規範,通過分析以後會產生一個符合java規範的抽象語法樹。抽象語法樹就是一個結構化的語法表達式,做用就是將詞法用一個結構化的形式組合在一塊兒。繼承

Java的語法樹使java源碼更加結構化,每一個語法樹上的節點都是一個JCTree實例接口

JCTree類有三個重要屬性:其實這三個屬性很好理解,爲了分辨出樹中的每個節點而出現的,定義了這三個屬性,能夠很快速的找到節點在樹中的層次結構和位置。編譯器

  1. TreeTag:每一個語法數節點都用整形常熟表示,每一個節點數值都是在前一個節點的基礎上執行加一操做,頂點節點TopLevel是1,那緊接着的Import節點就在TopLevel的基礎上加一,等於2  
  2. pos:整數。表示位置
  3. type:表示節點的類型

 

 

 

 

三、語義分析:對生成的抽象結構樹進一步分析,將複雜的語法結構轉換爲簡單的,易於理解和閱讀的語法結構。例如:將加強for循環foreach轉換爲for循環結構。通過語義分析以後會產生一個更加具體的抽象結構樹。源碼

語義分析實現的步驟;

語義分析主要是在Enter類中完成的,這個類主要有兩個步驟

(1)將全部類中出現的符號都輸入到類自身的符號表中,全部的類符號,類參數列表,超類符號,和繼承的接口類型符號都會存儲到未處理的符號列表中(由於類除了自身的符號以後還有其餘類中的引用,因此要進行分類)

(2)在未處理的符號列表中,將全部類符號解析到各自的類符號中,在MemberEnter.complete()類中完成。(解析語法樹,將全部的符號都添加到符號表中)

在Enter類解析的步驟中,還有一個輔助操做:

  • 添加默認的構造函數;
  • 接着下一步是處理註解:在JavaProcessingEnvironment類中完成;
  • 數據流分析,在Flow類中完成。  

    數據流分析實現的步驟:

    一、檢查變量在使用以前是否賦值,除了8中基本數據類型以外,還有String類型和其餘對象的引用在使用以前都須要賦值。

    二、使用final修飾的變量不會被從新賦值,若是重複複製會報錯;同時若是變量是靜態成員變量在定義的時候就必須賦值

    三、分析方法返回值類型

    四、全部的Checked Exception都必須向上拋出或者捕獲。

    五、全部的語句都會被執行,這個分析的是return語句以後是否還有語句,由於return以後的語句不會被執行。

  • 語義分析器的最後一個步驟,進一步處理語法樹,解決的問題
    •   消除無用的代碼,例如:if條件永遠爲false不會被執行的代碼塊  
    •         解除語法糖:說白了就是將例如加強的foreach循環轉換爲for循環
    •         變量自動類型轉換:例如:int類型和Integer類型之間相互轉換

四、字節碼:通過了上面的三個步驟以後,java源代碼就能夠被轉換成爲java虛擬機(JVM)可以別的字節碼文件。

代碼生成器:

  •   將源代碼轉換成符合JVM語法規範的命令形式,JVM的全部操做都是基於棧操做的,所以全部的操做都在進棧和出棧中完成。
  •         按照JVM文件組織的形式將字節碼輸出到後綴名爲class的字節碼文件中

整個業務流程:

 

 關於javac的基本原理就介紹到這裏,有興趣的能夠研究下Javac的源碼,能夠從OpenJdk下載到源碼。

相關文章
相關標籤/搜索