1. 程式人生 > >【java】之java代碼的執行機制

【java】之java代碼的執行機制

() alt 分享 str clas not roc 成員 輸入

要在JVM中執行java代碼必須要編譯為class文件,JDK是如何將Java代碼編譯為class文件,這種機制通常被稱為Java源碼編譯機制。

1、JVM定義了class文件的格式,但是並沒有定義如何將java源碼編譯為class文件,各個廠商在實現JDK時候通常會將符合java語言規範的源碼編譯為class文件的編譯器,如JDK就是javac

javac編譯生成class文件的步驟如下:

技術分享

1、分析和輸入到符號表 (Parse and Enter )

Parse過程所做的為詞法和語法分析,詞法分析(com.sun.tools.javac.parser.Scanner)要完成的是將代碼字符串轉變為token序列(例如Token.EQ(name:=));語法分析(com.sun.tools.javac.parser.Parser)要完成的是根據語法由token序列生成抽象語法樹。

Enter(com.sun,tools,javac.comp.Enter)過程為將符號輸入到符號表,通常包括確定類的超類型和接口,根據需要添加默認構造器,將類中出現的符號輸入類自身的符號表中等。

2、註解處理(Annotation Processing)

該步驟主要用於處理用戶自定的Annotation,可能帶來的好處是基於annotation來生成附加的代碼或進行一些特殊的檢查,從而節省一些共用的代碼的編寫,例如當采用Lombok時,可大大減少代碼量,編譯是引入Lombok對實體進行編譯後,再通過javap查看class文件,發現自動成get set toString等方法,此功能基於JSR269,在JDK1.6中提供支持,在Annotation Processing進行後,再次進入Parse and Enter步驟

3、語義分析和生成class文件(Analyse and Generate)

Analyse步驟基於抽象語法樹進行一系列的語法分析,包括將語法樹中的名字,表達式等元素與變量,方法,類型等聯系在一起,檢查變量使用前是否聲明,推導泛型方法的類型參數,檢查類型匹配性,進行常量折疊;檢查所有語句都可到達,檢查所有checked exception都被捕捉或者拋出,檢查變量的確定性賦值(如有返回值的方法必須定有返回值);檢查變量的確定性不重復賦值(例如聲明為final的變量);解除語法糖(消除if(false) )形式的無用代碼;將泛型Java轉為普通的Java,將含有語法糖的語法樹改為含有簡單語言結構的語法樹,例如for each循環,自動裝箱,拆箱等

在完成語義解析後,開始生成class文件(com.sun.tools.javac.jvm.Gen)生成的步驟,首先將實例成員初始化器手機到構造器中,將靜態成員初始化器手機為<cinit>();接著將抽象語法樹生成字節碼,采用的方法為後序遍歷語法樹,並進行最後的少量代碼轉換(例如String相加轉變為StringBuilder操作);最後從符號表生成class文件。

生成class文件除了javac之外,還可以通過ECJ(Eclipse compiler for java) 或者是Jikes等編譯器來將Java源碼編譯為class文件。

class文件不僅僅存放了字節碼,還存放了很多輔助JVM來執行class的附加信息,一個class文件包括

-結構信息

包括class文件格式版本號及各部分的數量和大小信息

-元數據

簡單的說可以認為是方法信息對用的java源碼中語句,表達式對應的信息,主要有字節碼,異常處理表,求值棧與局部變量區大小,求值棧的類型記錄,調試用符號信息。

【java】之java代碼的執行機制