我們手工執(zhí)行java程序是這樣的: 1 在記事本中或者是UE的文本編輯器中,寫好源程序; 2 使用javac命令把源程序編譯成.class文件; ConstantPool:符號表; FieldInfo:類中的成員變量信息; MethodInfo:類中的方法描述; Attribute:可選的附加節(jié)點(diǎn)。 FieldInfo節(jié)點(diǎn)包含成員變量的名稱,諸如public,private,static等的標(biāo)志。ConstantValue屬性用來存儲靜態(tài)的不變的成員變量的值。Deprecated和Synthetic被用來標(biāo)記一個成員變量是不被推薦的或由編譯器生成的。 3 有了.class文件,我們執(zhí)行 java 解釋命令就可以運(yùn)行java程序了。 現(xiàn)在我們主要討論一下,當(dāng)執(zhí)行 java這個命令后,會發(fā)生什么事情呢? 首先,JVM裝載.class,也就是類裝載器裝載類字節(jié)碼。一個類裝載器本身也是一個java類,所以,類裝載器自身也需要被另外一個類裝載器裝載,這就出現(xiàn)了類似先有蛋,還是先有雞的問題。但JAVA中的類裝載器的這個問題卻很容易解決。JAVA的虛擬機(jī)(JVM)中內(nèi)嵌了一個稱為Bootstrap類裝載器,它是用特定于操作系統(tǒng)的本地代碼實(shí)現(xiàn)的,屬于JAVA虛擬機(jī)的內(nèi)核,Bootstrap類不用專門的類裝載器去進(jìn)行裝載。Bootstrap類負(fù)責(zé)加載JAVA核心包中的類(即rt.jar文件中的類),這些類的Class.getClassLoader()方法返回值為null,即表示是Bootstrap類裝載器。JAVA核心包中有另外兩個類裝載器:ExtClassLoader和AppClassLoader,它們都是用JAVA語言編寫的JAVA類,其中ExtClassLoader類裝載負(fù)責(zé)加載存放在<JAVA_HOME>/jre/lib/ext目錄下的jar包中的類,AppClassLoader負(fù)責(zé)加載應(yīng)用程序的啟動執(zhí)行類,即當(dāng)使用java命令去啟動執(zhí)行一個類時,JAVA虛擬機(jī)使用AppClassLoader加載這個類。在編譯和運(yùn)行JAVA程序時,都會通過ExtClassLoader類裝載器去<JAVA_HOME>/jre/lib/ext目錄下的JAR包中搜索要加載的類,所以,如果將包含例如Servlet API的jar包或者是javamail.jar包復(fù)制到該目錄下,在編譯Servlet或JavaMail程序時,就不必在CLASSPATH環(huán)境變量中增加包含Servlet API的jar包或者是javamail.jar包文件。 以上,就是一個JAVA程序執(zhí)行的大致過程。 ------------------------------------------ Java字節(jié)碼程序的執(zhí)行過程:![]() Java字節(jié)碼程序的執(zhí)行過程 Java程序在啟動的時候首先交給JVM(一個JVM的運(yùn)行創(chuàng)建一個獨(dú)立的進(jìn)程)一個擁有public static void main(string[] args)函數(shù)的類,JVM通過引導(dǎo)類加載器(Bootstrap ClassLoader)加載該類,加載完成之后進(jìn)行校驗(yàn)、內(nèi)存填充和結(jié)構(gòu)化(即連接--校驗(yàn)/準(zhǔn)備/分解),然后啟用一個線程執(zhí)行main函數(shù)(大多數(shù)可執(zhí)行程序都有像main一樣的入口函數(shù)約定,有些地方可以成為入口地址),在執(zhí)行main函數(shù)的過程中碰到新的類,將會再次用ClassLoader加載該類,重復(fù)連接,并且繼續(xù)執(zhí)行main中調(diào)用的其它函數(shù),依次反復(fù),直到特定的終止條件發(fā)生,程序退出。 JVM執(zhí)行連接是典型的動態(tài)鏈接,也就是在執(zhí)行過程中按需加載類,所有加載類的工作都交由ClassLoader來完成。在后面談到的Java字節(jié)碼類文件格式?就是ClassLoader加載之后交給虛擬機(jī)的字節(jié)碼格式,換句話來說JVM不管ClassLoader之前的類來源和格式,它只管ClassLoader加載之后的格式,理解這點(diǎn)很重要。 ClassLoader分為系統(tǒng)級和用戶自定義級兩類,通過用戶自定義類加載器,可以完成自定義的類加載方式(如何自定義請參考該章的實(shí)戰(zhàn)?部分)。 關(guān)于更多Java字節(jié)碼的執(zhí)行過程細(xì)節(jié),在后面內(nèi)容JVM抽象架構(gòu)?中將會更進(jìn)一步提到。 |
|