Java類加載器(ClassLoader)
雙親委派模式要求除了頂層的啟動類加載器外界酒,其余的類加載器都應(yīng)當(dāng)有自己的父類加載器褥实,請注意雙親委派模式中的父子關(guān)系并非通常所說的類繼承關(guān)系低斋,而是采用組合關(guān)系來復(fù)用父類加載器的相關(guān)代碼渗饮,類加載器間的關(guān)系如下:
TIM截圖20190116163949.png
雙親委派模式是在Java 1.2后引入的,其工作原理的是壤圃,如果一個類加載器收到了類加載請求夹孔,它并不會自己先去加載被盈,而是把這個請求委托給父類的加載器去執(zhí)行,如果父類加載器還存在其父類加載器搭伤,則進一步向上委托只怎,依次遞歸,請求最終將到達頂層的啟動類加載器怜俐,如果父類加載器可以完成類加載任務(wù)身堡,就成功返回,倘若父類加載器無法完成此加載任務(wù)拍鲤,子加載器才會嘗試自己去加載贴谎,這就是雙親委派模式
3 雙親委派模式優(yōu)勢
- 采用雙親委派模式的是好處是Java類隨著它的類加載器一起具備了一種帶有優(yōu)先級的層次關(guān)系,通過這種層級關(guān)可以避免類的重復(fù)加載季稳,當(dāng)父親已經(jīng)加載了該類時擅这,就沒有必要子ClassLoader再加載一次。
- 其次是考慮到安全因素景鼠,java核心api中定義類型不會被隨意替換仲翎,假設(shè)通過網(wǎng)絡(luò)傳遞一個名為java.lang.Integer的類,通過雙親委托模式傳遞到啟動類加載器,而啟動類加載器在核心Java API發(fā)現(xiàn)這個名字的類谭确,發(fā)現(xiàn)該類已被加載,并不會重新加載網(wǎng)絡(luò)傳遞的過來的java.lang.Integer票渠,而直接返回已加載過的Integer.class逐哈,這樣便可以防止核心API庫被隨意篡改。
- 可能你會想问顷,如果我們在classpath路徑下自定義一個名為java.lang.SingleInterge類(該類是胡編的)呢昂秃?該類并不存在java.lang中,經(jīng)過雙親委托模式杜窄,傳遞到啟動類加載器中肠骆,由于父類加載器路徑下并沒有該類,所以不會加載塞耕,將反向委托給子類加載器加載蚀腿,最終會通過系統(tǒng)類加載器加載該類。但是這樣做是不允許扫外,因為java.lang是核心API包莉钙,需要訪問權(quán)限,強制加載將會報出如下異常
java.lang.SecurityException: Prohibited package name: java.lang