javac編譯器將Java源碼編譯成字節碼主要會經歷4個步驟:
詞法解析 ➙ 語法解析 ➙ 語義分析 ➙ 生成字節碼
詞法解析:
詞法解析要做的事情就是將Java源碼中的關鍵字和標識符等內容轉換爲符合Java語法規範的Token序列,然後按照指定的順序規則進行匹配校驗。
那什麼是符合Java語法規範的Token序列?Token序列是一組枚舉類型的常量,符合Java語法規範並與源碼字符集合相對應。
源碼字符集合是如何轉換成Token的?在轉換之前,先會將每一個字符集合都轉換爲一個對應的Name對象,然後會將Token中的所有枚舉常量全部轉換爲Name對象並存儲在Name對象內部類Table中,這樣就建立起了源碼字符集和Token之間的關係。
將源碼字符集合轉換成Token後,詞法解析器又是採用什麼方式保存?源碼字符集和Token之間的對應關係是保存在Keywords類中的數組key中。
校驗Token的匹配規則,這也是詞法解析的核心。按照Token的匹配規則依次解析出package、import關鍵字聲明,這些Token都匹配成功後開始解析class主體信息。
語法解析:
語法解析就是將匹配後的Token序列整合爲一顆結構化的抽象語法樹。
其實詞法解析中對Token的匹配規則的解析校驗和語法解析是同時在一個方法下完成的,當詞法解析完成某個關鍵字的轉換,匹配成功後就會根據這個Token對應的Name對象解析出相應的語法節點。語法解析按照Token序列指定的順序規則依次用不同的方法解析出package語法節點、import語法樹點以及class語法樹。最終將package語法節點、import語法樹點和class語法樹等內容信息全部整合到一顆語法樹。
到此可以說編譯器在生成字節碼之前,編譯雛形已經成功構建好了。但是畢竟只是雛形,語法解析後的這顆結構化抽象語法樹是不完善的,還不能直接進入字節碼編譯階段。
語義分析:
語義分析就是爲了完善之前語法解析後產生的那顆語法樹。
語義分析主要做以下一些工作:
爲沒有構造方法的類型添加默認無參構造方法
檢查任何類型的變量在使用前是否都已經初始化
檢查變量類型是否與值匹配
將String類型的常量進行合併處理
檢查代碼中的所有操作語句是否可達
異常檢查
經歷這一系列語義分析步驟之後就構成了一個擴充後的完善的語法樹。
生成字節碼:
調用相關方法將最終的這顆語法樹編譯爲符合Java虛擬機規範的字節碼文件。