Javac的實現過程


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

首先弄明白什么是Javac?

Javac是一種編譯器,將一種語言轉換為另一種語言規范。編譯器的作用就是將符合java語言規范的源代碼轉化為JVM虛擬機能夠識別的字節碼文件的過程。

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

 

 

 

編譯過程的原理:

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

2、語法分析:對Token流進行分析。分析出這些關鍵字組合在一起是否符合java語言規范,經過分析之后會產生一個符合java規范的抽象語法樹。抽象語法樹就是一個結構化的語法表達式,作用就是將詞法用一個結構化的形式組合在一起。

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

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

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

 

 

 

 

3、語義分析:對生成的抽象結構樹進一步分析,將復雜的語法結構轉換為簡單的,易於理解和閱讀的語法結構。例如:將增強for循環foreach轉換為for循環結構。經過語義分析之后會產生一個更加具體的抽象結構樹。

語義分析實現的步驟;

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

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

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

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

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

    數據流分析實現的步驟:

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

    2、使用final修飾的變量不會被重新賦值,如果重復復制會報錯;同時如果變量是靜態成員變量在定義的時候就必須賦值

    3、分析方法返回值類型

    4、所有的Checked Exception都必須向上拋出或者捕獲。

    5、所有的語句都會被執行,這個分析的是return語句之后是否還有語句,因為return之后的語句不會被執行。

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

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

代碼生成器:

  •   將源代碼轉換成符合JVM語法規范的命令形式,JVM的所有操作都是基於棧操作的,因此所有的操作都在進棧和出棧中完成。
  •         按照JVM文件組織的形式將字節碼輸出到后綴名為class的字節碼文件中

整個業務流程:

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM