資源描述:
《Java虛擬機JVM類加載學(xué)習(xí)筆記》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、深入Java虛擬機JVM類加載初始化學(xué)習(xí)筆記劉巖Email:suhuanzheng7784877@163.com1.Classloader的作用,概括來說就是將編譯后的class裝載、加載到機器內(nèi)存中,為了以后的程序的執(zhí)行提供前提條件。2.一段程序引發(fā)的思考:風(fēng)中葉老師在他的視頻中給了我們一段程序,號稱是世界上所有的Java程序員都會犯的錯誤。詭異代碼如下:packagetest01;classSingleton{publicstaticSingletonsingleton=newSingleton();publicstaticinta;pu
2、blicstaticintb=0;privateSingleton(){super();a++;b++;}publicstaticSingletonGetInstence(){returnsingleton;}}publicclassMyTest{/***@paramargs*/publicstaticvoidmain(String[]args){Singletonmysingleton=Singleton.GetInstence();System.out.println(mysingleton.a);System.out.println(m
3、ysingleton.b);}}7/7一般不假思索的結(jié)論就是,a=1,b=1。給出的原因是:a、b都是靜態(tài)變量,在構(gòu)造函數(shù)調(diào)用的時候已經(jīng)對a和b都加1了。答案就都是1。但是運行完后答案卻是a=1,b=0。下面我們將代碼稍微變一下publicstaticSingletonsingleton=newSingleton();publicstaticinta;publicstaticintb=0;的代碼部分替換成publicstaticinta;publicstaticintb=0;publicstaticSingletonsingleton=new
4、Singleton();效果就是剛才預(yù)期的a=1,b=1。為什么呢,這3句無非就是靜態(tài)變量的聲明、初始化,值的變化和聲明的順序還有關(guān)系嗎?Java不是面向?qū)ο蟮膯幔吭趺春徒Y(jié)構(gòu)化的語言似地,順序還有關(guān)系。這個就是和Java虛擬機JVM加載類的原理有著直接的關(guān)系。1.類在JVM中的工作原理要想使用一個Java類為自己工作,必須經(jīng)過以下幾個過程1):類加載load:從字節(jié)碼二進制文件——.class文件將類加載到內(nèi)存,從而達到類的從硬盤上到內(nèi)存上的一個遷移,所有的程序必須加載到內(nèi)存才能工作。將內(nèi)存中的class放到運行時數(shù)據(jù)區(qū)的方法區(qū)內(nèi),之后在堆區(qū)
5、建立一個java.lang.Class對象,用來封裝方法區(qū)的數(shù)據(jù)結(jié)構(gòu)。這個時候就體現(xiàn)出了萬事萬物皆對象了,干什么事情都得有個對象。就是到了最底層究竟是雞生蛋,還是蛋生雞呢?類加載的最終產(chǎn)物就是堆中的一個java.lang.Class對象。2):連接:連接又分為以下小步驟驗證:出于安全性的考慮,驗證內(nèi)存中的字節(jié)碼是否符合JVM的規(guī)范,類的結(jié)構(gòu)規(guī)范、語義檢查、字節(jié)碼操作是否合法、這個是為了防止用戶自己建立一個非法的XX.class文件就進行工作了,或者是JVM版本沖突的問題,比如在JDK6下面編譯通過的class(其中包含注解特性的類),是不能在
6、JDK1.4的JVM下運行的。準(zhǔn)備:將類的靜態(tài)變量進行分配內(nèi)存空間、初始化默認(rèn)值。(對象還沒生成呢,所以這個時候沒有實例變量什么事情)解析:把類的符號引用轉(zhuǎn)為直接引用(保留)3):類的初始化:將類的靜態(tài)變量賦予正確的初始值,這個初始值是開發(fā)者自己定義時賦予的初始值,而不是默認(rèn)值。2.類的主動使用與被動使用以下是視為主動使用一個類,其他情況均視為被動使用!1):初學(xué)者最為常用的new一個類的實例對象(聲明不叫主動使用)2):對類的靜態(tài)變量進行讀取、賦值操作的。3):直接調(diào)用類的靜態(tài)方法。4):反射調(diào)用一個類的方法。5):初始化一個類的子類的時候
7、,父類也相當(dāng)于被程序主動調(diào)用了(如果調(diào)用子類的靜態(tài)變量是從父類繼承過來并沒有復(fù)寫的,那么也就相當(dāng)于只用到了父類的東東,和子類無關(guān),所以這個時候子類不需要進行類初始化)。6):直接運行一個main函數(shù)入口的類。所有的JVM實現(xiàn)(不同的廠商有不同的實現(xiàn),有人就說IBM的實現(xiàn)比Sun的要好……)在首次主動調(diào)用類和接口的時候才會初始化他們。7/71.類的加載方式1):本地編譯好的class中直接加載2):網(wǎng)絡(luò)加載:java.net.URLClassLoader可以加載url指定的類3):從jar、zip等等壓縮文件加載類,自動解析jar文件找到cla
8、ss文件去加載util類4):從java源代碼文件動態(tài)編譯成為class文件2.類加載器JVM自帶的默認(rèn)加載器1):根類加載器:bootstrap,由C++編寫,所