黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

JVM學(xué)習(xí)筆記(八):類加載器以及雙親委派模型

系統(tǒng) 1953 0

本章內(nèi)容根據(jù)《深入理解Java虛擬機(jī)》第7章部分內(nèi)容整理

?

? ? 1.什么是類加載器?

? ?在類加載階段,有一步是“通過類的全限定名來獲取描述此類的二進(jìn)制字節(jié)流”,而所謂的類加載器就是實(shí)現(xiàn)這個(gè)功能的一個(gè)代碼模塊,這個(gè)動(dòng)作是在Java虛擬機(jī)外部實(shí)現(xiàn)的,這樣做可以讓應(yīng)用程序自己決定如何去獲取所需要的類。

? ?類加載器的作用:首先類加載器可以實(shí)現(xiàn)最本質(zhì)的功能即類的加載動(dòng)作。同時(shí),它還能夠結(jié)合java類本身來確定該類在Java虛擬機(jī)中的唯一性。用通俗的話來說就是:比較兩個(gè)類是否相等,只有這兩個(gè)類是由同一個(gè)類加載器加載才有意義。否則,即使這兩個(gè)類是來源于同一個(gè)Class文件,只要加載它們的類加載器不同,那么這兩個(gè)類必定不相等。

? ? 2.雙親委派模型

? ?從虛擬機(jī)的角度來說,只存在兩種不同的類加載器:一種是啟動(dòng)類加載器(Bootstrap ClassLoader),該類加載器使用C++語言實(shí)現(xiàn),屬于虛擬機(jī)自身的一部分。另外一種就是所有其它的類加載器,這些類加載器是由Java語言實(shí)現(xiàn),獨(dú)立于JVM外部,并且全部繼承自抽象類java.lang.ClassLoader。

? ?從Java開發(fā)人員的角度來看,大部分Java程序一般會(huì)使用到以下三種系統(tǒng)提供的類加載器:

? ?1)啟動(dòng)類加載器(Bootstrap ClassLoader):負(fù)責(zé)加載JAVA_HOME\lib目錄中并且能被虛擬機(jī)識(shí)別的類庫到JVM內(nèi)存中,如果名稱不符合的類庫即使放在lib目錄中也不會(huì)被加載。該類加載器無法被Java程序直接引用。

? ?2)擴(kuò)展類加載器(Extension ClassLoader): 按《深入理解java虛擬機(jī)》這本書上所說,該加載器主要是負(fù)責(zé)加載JAVA_HOME\lib\ext目錄中的類庫,但是貌似在JDK的安裝目錄下,沒看到該指定的目錄 。該加載器可以被開發(fā)者直接使用。

? ?3)應(yīng)用程序類加載器(Application ClassLoader):該類加載器也稱為系統(tǒng)類加載器,它負(fù)責(zé)加載用戶類路徑(Classpath)上所指定的類庫,開發(fā)者可以直接使用該類加載器,如果應(yīng)用程序中沒有自定義過自己的類加載器,一般情況下這個(gè)就是程序中默認(rèn)的類加載器。

? ?我們的應(yīng)用程序都是由這三類加載器互相配合進(jìn)行加載的,我們也可以加入自己定義的類加載器。這些類加載器之間的關(guān)系如下圖所示:

類加載器的雙親委派模型

? ?如上圖所示的類加載器之間的這種層次關(guān)系,就稱為類加載器的雙親委派模型(Parent Delegation Model)。該模型要求除了頂層的啟動(dòng)類加載器外,其余的類加載器都應(yīng)當(dāng)有自己的父類加載器。子類加載器和父類加載器不是以繼承(Inheritance)的關(guān)系來實(shí)現(xiàn),而是通過組合(Composition)關(guān)系來復(fù)用父加載器的代碼。

? ?雙親委派模型的工作過程為: 如果一個(gè)類加載器收到了類加載的請求,它首先不會(huì)自己去嘗試加載這個(gè)類,而是把這個(gè)請求委派給父類加載器去完成,每一個(gè)層次的加載器都是如此,因此所有的類加載請求都會(huì)傳給頂層的啟動(dòng)類加載器,只有當(dāng)父加載器反饋?zhàn)约簾o法完成該加載請求(該加載器的搜索范圍中沒有找到對(duì)應(yīng)的類)時(shí),子加載器才會(huì)嘗試自己去加載

? ?使用這種模型來組織類加載器之間的關(guān)系的好處是Java類隨著它的類加載器一起具備了一種帶有優(yōu)先級(jí)的層次關(guān)系。例如java.lang.Object類,無論哪個(gè)類加載器去加載該類,最終都是由啟動(dòng)類加載器進(jìn)行加載,因此Object類在程序的各種類加載器環(huán)境中都是同一個(gè)類。否則的話,如果不使用該模型的話,如果用戶自定義一個(gè)java.lang.Object類且存放在classpath中,那么系統(tǒng)中將會(huì)出現(xiàn)多個(gè)Object類,應(yīng)用程序也會(huì)變得很混亂。如果我們自定義一個(gè)rt.jar中已有類的同名Java類,會(huì)發(fā)現(xiàn)JVM可以正常編譯,但該類永遠(yuǎn)無法被加載運(yùn)行。

? ?在rt.jar包中的java.lang.ClassLoader類中,我們可以查看類加載實(shí)現(xiàn)過程的代碼,具體源碼如下:

      protected synchronized Class<?> loadClass(String name, boolean resolve)	throws ClassNotFoundException{
	// First, check if the class has already been loaded
	Class c = findLoadedClass(name);
	if (c == null) {
		try {
			if (parent != null) {
				c = parent.loadClass(name, false);
			} else {
				c = findBootstrapClassOrNull(name);
			}
		} catch (ClassNotFoundException e) {
			// ClassNotFoundException thrown if class not found
			// from the non-null parent class loader
		}
		if (c == null) {
			// If still not found, then invoke findClass in order
			// to find the class.
			c = findClass(name);
		}
	}
	if (resolve) {
		resolveClass(c);
	}
	return c;
}
    

?

? ?通過上面代碼可以看出,雙親委派模型是通過loadClass()方法來實(shí)現(xiàn)的,根據(jù)代碼以及代碼中的注釋可以很清楚地了解整個(gè)過程其實(shí)非常簡單:先檢查是否已經(jīng)被加載過,如果沒有則調(diào)用父加載器的loadClass()方法,如果父加載器為空則默認(rèn)使用啟動(dòng)類加載器作為父加載器。如果父類加載器加載失敗,則先拋出ClassNotFoundException,然后再調(diào)用自己的findClass()方法進(jìn)行加載。

JVM學(xué)習(xí)筆記(八):類加載器以及雙親委派模型介紹


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論