深入java虛擬機教學與程序的生命周期_第1頁
深入java虛擬機教學與程序的生命周期_第2頁
深入java虛擬機教學與程序的生命周期_第3頁
深入java虛擬機教學與程序的生命周期_第4頁
深入java虛擬機教學與程序的生命周期_第5頁
已閱讀5頁,還剩55頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

圣思園科 主講人張AllJava虛擬機與程序的生命周 加載:查找并加載類的二進制數連解析:把類中的符號轉換為直接,類的加載、連掛與初始化,加加 Java程序對類的使用方式可分為兩主動使使 主動使用(六種) 式都被看作是對類的使用,都不會導加載.class文件的方從zip,jar等歸檔文件中加載.class'..· l1

i 構l

!t!tIIl1 I lI !!ClassClass對象封裝了類在方法區內的數據結,并且向Java程序員提供了方法區內有兩種類型的類加載Java虛擬機自帶的加根類加載器java.lang.ClassLoader類的驗證的內類的驗證的驗證主要包括以下內容類文件的結構檢查:確保類文件遵從Java類文件的固定m士”語義檢查:確保類本身符合Java語言的語 定,比如驗證final類型的類沒子類,以及”“f.U.大土中兒『凸以1--:::1一區1~lill.O字節碼驗:確保字節碼流可以被Java虛擬機安全地執行。字節碼流代衣』a方法(包括靜態方法和實例方法),它是由被稱 作碼的單字節指令組成后都跟若一個或多個操作數。字節碼驗證步驟會檢查每個操作碼是否合法,即是否有諸合法的操作數。二進制兼容的驗證:確保相 的類之間協調一致。例如在Worker類的toWork()方法中會調用Car類的run()方法。Java虛擬機在驗證Worker類時會檢查在方法區內是否存在Car類的runO方法,假如不存在(當Worker類和r類的版本不兼容,就會出現這種問題),就會拋出NoSu ethodError錯誤類的準各準備階段,Jav虛擬機為類的靜態變品分配內存,并設笠默認的初始值。例如對千以下Sample類,在準備階段,將為int類型的靜態變栽a分配4個字節的內存空間,并且賦予默認值O,為long類型的靜態變址b分配8個字節的內存空間,并且汃認值0 ccp出li

=..C2}類的解析在解析階段,Java虛擬機會把類的一進制數據中的符號 替換為直接 。例如在Worker類的gotoWork()方法中會 Car類的run()方沁心licvoidgocam()】}Worker類的二進制數據中,包含了一個對Car類的runO方法的符 的全名和相關描述符組成。在解析階段,Java虛擬機會把這個符號 替換為一個指針,該指針指向Car類的run()方法在方法區內的內存位翌,這個指針就是直接 類的初始化叨始化階段,Java虛擬機執行類的初始化心代碼塊中進行初始化。例如在以下代碼而靜態變員c沒有被顯式初始化,它將保持默認值0

的處進行初始化;(2)a和b都被顯式初始化p叩lieclasublic·stati

e{ longb;loatic壇2;

II )}類的初始化心、變亂 語句,以及靜態代碼塊都被看做類的初始化語句按照初始化語旬在類文件中的先后順序來依次執行它們。例如當以下Sample類被初化后,它的靜態變攬a的取值為4taticinca=l:Sta已c{a=2;}static{ a:::4;} voidmainStr江gargs1匈st如.outprintin正飛a);I打印類的初始化步主動使用(六種)式都被看作是使用,不會導致類的初類的初始化時機(3)當Java虛擬機初始化一個類時,要求它的所有父類都已經被初始化,但是在初始化一個類時,并不會先初始化它所實現的接口。在初始化一個接口時,并不會先初始化它的父接已。因此,一個父接口并不會因為它的子接口或者實現類的初始化而初始化。,白次使用特定接口的靜態變量時,才會導致該接口的初始化。,類加載器把類加載到Java虛擬機中。從JDK 1.2版本開始,類的加載過中叩托機制,這種機制能更好地保證Java平臺的安全。在此委托機制中,除了Java帶的根類加載器以外,其余的類加載器都有且只有一個父加載器。當Java請求加載器loader]加載Sample類時,loaderI首先委托自己的父加載器去加載則由父加載器完成加載任務,否則才由加載器loaderl本身加 Java虛擬機自帶了以下幾種加載器積(Bootstrap)類加載器:該加載器沒有父加載器。它負責加載虛擬機的就是由根類加載器加載的。根類加載器從系統屈性sun.boot.class.path所指定的加載類庫。根類加載器的實現依賴千底層操作系統,屈千虛擬機的實現的一部分,它并沒有繼承java.lang.CI邸sLoader大擴展(Extension)類加載器:它的父加載器為根類加載器。它從爾統屬性所指定 中加載類庫,或者從JDK的安 的 F加載類庫,如果把用戶創建的JAR文件放在這個也會自動巾擴展類加載器加載。擴展類加載器是純Java大,走java.lang.ClassLoader類的子類系統(System)類加載器:也稱為應用類加載器,它的父加載器為擴展類加它從環境交址classpath或者系統屬性java.classpath所指定的中加載類,它是用戶自定義的類加載器的默認父加載器。系統類加載器是純Java類,是java.lang.ClassLoader類的子類。以力以力力力力力,J、J盧[、盧[類加載的父委托機制托機制中,各個加載器按照父子關系形成了樹形結構,除了根類加載器余的類加載器都有且只有一個父加載器,類加載的父委托機制lo吐r2 lo吐r2、pgIpgI類加載的父委托機制Class哱叩1eClas年loader2loadClassloader2首先 名空間中查找Sample類是否已經被加載,如果已經加載就直接返回代表Sample類的Class對象 amp比欠還沒有被加載,loader2首先請求loaderI代為加載,統類加載器代為加載,系統類加載器再請求擴展類加載器代為加載,擴展類加再請求根類加載器代為加載。若根類加載器和擴展類加載器都不能加載,則系統試加載,若能加載成功,則將Sample類所對應的Class對象的 loader1再 返回給loader2,從而成功將S皿ple類加載進虛擬心統類加載器不能加載S印1ple類,則loaderl嘗試加載Sample類,若loader]也不能成功加載,則loader2嘗試加載。若所有的父加載器及loade立本身都不能加載,則拋出assNotFoundException異常類加載的父委托機制·E”··E”,口,類加載的父委托機制口,二rl二rl類加載的父委托機制,類加載的父委托機制托機制的優點是能夠提高軟件系統的安全性。因為在此機制下,用戶自定義的類加載器不可能加載應該由父加載器加載的可靠類,從而防止不可靠甚至的代碼代替由父加載器加載的可靠代碼。例如,java.lang.Ob_ject類總是由根類加載器加他任何用戶自定義的類加載器都不可能加載含有代碼的命名空間 個類;在不同名空間中,有可能會出現類的完整名字(包括類的包名)相同的 -運行時包同一個運行時包,不僅要看它們的包名是否相同,還要看定義類加載司一運行時包的類才能互 包可見(即默 級別)的樣的限制能避免用戶自定義的類冒充 類庫的類,去 類庫的包可見成貝。假設用戶自己定義了一個類java.lang.Spy,并由用戶自定義的類加載器加 類庫java.lang.*由不同的加載器加載,它們屈千不同的運行時包,所以java.lang.Spy不能 類庫java.lang包中的包可見成貝。創建用戶自定義的類加載器創建用戶自己的類加載器,只需要擴展java.lang.ClassLoader類,然后覆蓋它的findClass(Stringname)方法即可,該方法根據參數指定的類的名字,返回對應的Cla對象的。創霪用戶自定義的類加載器K吐 C出5'1 1創壅用戶自定義的類加載器“'執行loader2.JoadClass(11Sample”)時,先由它上層的所有父加載器嘗試加mple奀。loaderl從D:\myapp\serverlib 下成功地加載fSample類,因此loader是Sample類的定義類加載器,1oaderl和loader2挫Sample類的初始類加載如執行loader3.loadClassC'Sample”)時,先由它上層的所有父加載ample類。loader3的父加載器為根類加載器,它無法加載Sample類,接D:\myapp\otherlib 下成功地加載了Sample類,因此loaderj走amp

、...A從創霪用戶自定義的類加載器,-,?P-----------,-,?P

--,lIli

bIbII'II·L1.I.Ii'II'的Cll l創建用戶自定義的類加載器(2)在Samole類中主動使用了Dog類,當執行Sample類的構造方法中的newJava虛擬機而要先加載Dog類,到底用哪個類加載器加載呢?從步驟(l)的打印結果可以石出,加載Sample類的loaderI還加載了Dog類,Java虛擬機會用SamDl的定義類加載器上加載Dog類,加載過程也同樣采用父親委托機制。為了驗證這二.D:\myapp\serverlib目錄下的Dog.class文件刪除,然后在D:\m存放一個Dog.class文件,此時程序的打印結果為,Samplefloaded切Dog loadedbyloader3

ld609-創建用戶自定義的類加載器由此可見,當由loaderl加載的Sample類首次主動使用Dog類時,Dog類由系_加載器加載。如果把D:\myapp\serverlib和D:\myapp\syslib 下的Dog.clas"'都刪除,然后在D:\myapp\ 下存放一個Dog.class文件,,此時的 結構參見圖10-8。當由loader!加載的Samp1e類首次主動使用Dog類時,由千loader I及匕的父加載器都無法加載Dog類,因此test{loader2)方 拋出ClassNotFoundException。創霪用戶自定義的類加載器II ,不同類加載 同一個命名空間內的類是相互可見的加載 名空l同包含所有父加載 名空間。因此由子加載器加載E看見父加載器加載的類。例如系統類加載器加載的類能看見根加載的大由父加載器加載的類不能看見子加載器加載的大如果兩個加載器之間沒有直接或間接的父子關系,那么它們各自加載的類相修改MyClassLoader類的源代不同類加載 yClassLoader類由系統類加載器加載,而Sample類由loaderl類加載,因此ader類的main()方法中使用lassDefFoundE訂or錯誤個不同命名空間內的類相互不可見時,可采用Java反射機制 對方實的屬性和方法。如果把MyClassLoader類的main()方法替換為如下代碼:不同類加載 如果把件拷貝到

的Sample.class和Dog.class刪除,再把這芯,然后運行例程10-8中的main()方法,也能正常運行此時MyClassLoader類和Sample六間內,因此

系統類加載器加載,由千它們位于同一個命類的卸載當Sample類被加載、連接和初始化后,它的生命周期就開始了。當代表的Class對象不再 ,即不可觸及時,Class對象就會結束生命周期方法區內的數據也會被卸載,從而結束Sample類的生命周期。由此可見,一個類何時結束生命周期,取決于代表它的Class對象何時結束生命周期,類的卸載由Java虛擬機自帶的類加載器所加載的類,在虛擬機的生命周期中,始終不入卸載。前面已經介紹過,Java虛擬機自帶的類加載器包括根類加載器、擴展類加載器和系統類加載器。Java虛擬機本身會始終 這些類加載器,而這些類加載器則會始 它們所加載的類的Class對象,因此這些Class對象始終是可觸及的。,類的卸載把Sampleclass和Dogclass拷貝到D:\myappClassLoader類的main()方法替換為如下代碼.publics,ta,ticvoidmain;(砒 a為6) thi:OI泗Ex七

錄 歡lassLoader loaderl··=n的歡lass邁忒erPloaderi”)l.setP忒h(“D:\\邱,ap_p\\serverlib\\"'',,;ClassobjClss=16adrl.loadClass(飛迪lJ)le"};SyB七巳n.out.print1n尸objClasS'!;JhashCode 飛objClass.hashCode(l);

IIII@II

e(}

/III?II?lloaderln氐邸lasLoaderJ"'loaderl勹,objClass=stem.out,p豆類的卸載運行以上

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論