上篇文章說了java類的加載,驗(yàn)證、準(zhǔn)備、解析、初始化。類的初始化必須是類加載完才執(zhí)行,所以類的構(gòu)造方法初始化是在靜態(tài)方法之后執(zhí)行。
JVM類加載機(jī)制-JVM(一)
一、類加載和雙親委派機(jī)制
前面類加載主要通過類加載器實(shí)現(xiàn),類加載器有這幾種:
- 引導(dǎo)類加載器:負(fù)責(zé)加載支撐JVM運(yùn)行的位于JRE的lib目錄下核心類庫,比如chaset.jar和rt.jar等。(c++實(shí)現(xiàn))
- 擴(kuò)展類加載器:負(fù)責(zé)加載支撐JVM運(yùn)行的位于jre的lib目錄下的ext擴(kuò)展目錄中的jar類包。
- 應(yīng)用程序加載器:負(fù)責(zé)加載classPath路徑下的類包,主要加載自己寫的類。
- 自定義加載器:負(fù)責(zé)加載用戶自定義路徑下的類包。
?
?
由上面代碼執(zhí)行的結(jié)果可以看到:
為什么第一個(gè)打印的是null呢,因?yàn)橐龑?dǎo)類加載器是c++實(shí)現(xiàn)的,java不會(huì)顯示。
同理parentBootStrap就是加載器就是基類加載器,也是null。它的子類是ext加載器,ext的子類是app加載器,可以通過getSystemClassLoader來獲取到。
為什么appClassLoader明明是最子類,而它會(huì)打印所有的包呢?
這就是雙親委派設(shè)置導(dǎo)致如此的,因?yàn)槊看渭虞d會(huì)從他的父加載器去加載,當(dāng)bootStrap從核心類庫加載不到,才會(huì)依次讓子加載器嘗試加載。
?
Launcher類最核心的代碼是這兩塊
getExtClassLoader() 和 getAppClassLoader()
ExtClassLoader是構(gòu)造擴(kuò)展類加載器,構(gòu)造過程中將其父加載器設(shè)置為null。
getAppClassLoader構(gòu)造應(yīng)用類加載器,構(gòu)造過程中將父加載器設(shè)置為ExtClassLoader。
?
需要設(shè)置一下,equals我們自己的類,就可以只看我們自己的斷點(diǎn)。
當(dāng)我們運(yùn)行昨天寫的代碼,斷點(diǎn)就會(huì)走到loadClass這里,點(diǎn)進(jìn)去他的super。
這里的findLoaderClass代表如果找到就直接返回。
這里第一次進(jìn)來肯定是null,所以判斷他的parent。
我們這里的this指的是appClassLoader,
所以他的父加載器我們之前看了是ExtClassLoader。
這時(shí)候遞歸調(diào)用這個(gè)loadClass,這時(shí)候則是ExtClassLoader調(diào)用。
這時(shí)候ExtClassLoader的父加載器是null,這時(shí)候走下面findBootstrap引導(dǎo)類加載器。
這時(shí)bootStrap類加載器肯定返回null。
于是開始進(jìn)入findClass。
這里的findClass則是會(huì)調(diào)用URLClassLoader里的findClass方法。文章來源:http://www.zghlxwxcb.cn/news/detail-510796.html
這里會(huì)嘗試加載又會(huì)回到appClassLoader。文章來源地址http://www.zghlxwxcb.cn/news/detail-510796.html
到了這里,關(guān)于JVM類加載&雙親委派-JVM(二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!