一看你就懂竟坛,Java中的ClassLoader詳解

作者簡(jiǎn)介 原創(chuàng)微信公眾號(hào)郭霖 WeChat ID: guolin_blog

本篇是fank909的第四篇投稿哪自,詳細(xì)地介紹了Java中的ClassLoader。由于篇幅較長(zhǎng)爆价,我這里只推出了基礎(chǔ)部分垦巴,如果讀完感興趣,大家可以點(diǎn)擊文末閱讀原文查看進(jìn)階部分铭段。

frank909的博客地址:

http://blog.csdn.net/briblue

前言

ClassLoader 翻譯過(guò)來(lái)就是 類加載器骤宣,普通的Java開(kāi)發(fā)者其實(shí)用到的不多,但對(duì)于某些框架開(kāi)發(fā)者來(lái)說(shuō)卻非常常見(jiàn)序愚。理解 ClassLoader 的加載機(jī)制憔披,也有利于我們編寫(xiě)出更高效的代碼。

ClassLoader 的具體作用就是將 class文件 加載到 jvm虛擬機(jī) 中去爸吮,程序就可以正確運(yùn)行了活逆。但是,jvm 啟動(dòng)的時(shí)候拗胜,并不會(huì)一次性加載所有的class文件,而是根據(jù)需要去動(dòng)態(tài)加載怒允。想想也是的埂软,一次性加載那么多jar包那么多class,那內(nèi)存不崩潰纫事。本文的目的也是學(xué)習(xí) ClassLoader 這種加載機(jī)制勘畔。

備注:本文篇幅比較長(zhǎng),但內(nèi)容簡(jiǎn)單丽惶,大家不要恐慌炫七,安靜地耐心翻閱就是

Class文件的認(rèn)識(shí)

我們都知道在Java中程序是運(yùn)行在虛擬機(jī)中,我們平常用文本編輯器或者是IDE編寫(xiě)的程序都是.java格式的文件钾唬,這是最基礎(chǔ)的源碼万哪,但這類文件是不能直接運(yùn)行的侠驯。如我們編寫(xiě)一個(gè)簡(jiǎn)單的程序 HelloWorld.java

如圖:

然后,我們需要在命令行中進(jìn)行java文件的編譯:

javacHelloWorld.java

可以看到目錄下生成了.class文件奕巍。我們?cè)購(gòu)拿钚兄袌?zhí)行命令:

javaHelloWorld

上面是基本代碼示例吟策,是所有入門(mén)JAVA語(yǔ)言時(shí)都學(xué)過(guò)的東西,這里重新拿出來(lái)是想讓大家將焦點(diǎn)回到 class文件 上的止,class文件 是字節(jié)碼格式文件檩坚,java虛擬機(jī)并不能直接識(shí)別我們平常編寫(xiě)的 .java源文件,所以需要javac這個(gè)命令轉(zhuǎn)換成 .class文件诅福。另外匾委,如果用 C 或者?Python?編寫(xiě)的程序正確轉(zhuǎn)換成 .class文件后,java虛擬機(jī)也是可以識(shí)別運(yùn)行的氓润。更多信息大家可以參考這篇:

http://blog.csdn.net/zhangjg_blog/article/details/21486985

了解了 .class文件后赂乐,我們?cè)賮?lái)思考下,我們平常在 Eclipse 中編寫(xiě)的 java程序 是如何運(yùn)行的旺芽,也就是我們自己編寫(xiě)的各種類是如何被加載到 jvm(java虛擬機(jī)) 中去的沪猴。

你還記得Java環(huán)境變量嗎

初學(xué)java的時(shí)候,最害怕的就是下載 JDK 后要配置環(huán)境變量了采章,關(guān)鍵是當(dāng)時(shí)不理解运嗜,所以戰(zhàn)戰(zhàn)兢兢地照著書(shū)籍上或者是網(wǎng)絡(luò)上的介紹進(jìn)行操作。然后下次再弄的時(shí)候悯舟,又忘記了而且是必忘担租。當(dāng)時(shí),心里的想法很氣憤的抵怎,想著是–這東西一點(diǎn)也不人性化奋救,為什么非要自己配置環(huán)境變量呢?太不照顧菜鳥(niǎo)和新手了反惕,很多菜鳥(niǎo)就是因?yàn)榭ㄔ诃h(huán)境變量的配置上尝艘,遭受了太多的挫敗感。

因?yàn)槲沂窃赪indows下編程的姿染,所以只講Window平臺(tái)上的環(huán)境變量背亥,主要有3個(gè):JAVA_HOMEPATH悬赏、CLASSPATH狡汉。

JAVA_HOME

指的是你JDK安裝的位置,一般默認(rèn)安裝在C盤(pán)闽颇,如:

C:\ProgramFiles\Java\jdk1.8.0_91

PATH

將程序路徑包含在 PATH 當(dāng)中后盾戴,在命令行窗口就可以直接鍵入它的名字了,而不再需要鍵入它的全路徑,比如上面代碼中我用的到javacjava兩個(gè)命令兵多。一般的:

PATH=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;%PATH%;

也就是在原來(lái)的PATH路徑上添加JDK目錄下的bin目錄jre目錄的bin.

CLASSPATH

CLASSPATH=.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar

一看就是指向jar包路徑尖啡。需要注意的是前面的.;橄仆,.代表當(dāng)前目錄。

環(huán)境變量的設(shè)置與查看

設(shè)置可以右擊我的電腦可婶,然后點(diǎn)擊屬性沿癞,再點(diǎn)擊高級(jí),然后點(diǎn)擊環(huán)境變量矛渴,具體不明白的自行查閱文檔椎扬。查看的話可以打開(kāi)命令行窗口:

echo%JAVA_HOME%

echo%PATH%

echo%CLASSPATH%

好了,扯遠(yuǎn)了具温,知道了環(huán)境變量蚕涤,特別是 CLASSPATH 時(shí),我們進(jìn)入今天的主題Classloader.

Java類加載流程

Java語(yǔ)言系統(tǒng)自帶有三個(gè)類加載器:

Bootstrap ClassLoader最頂層的加載類铣猩,主要加載核心類庫(kù)揖铜,%JRE_HOME%\lib 下的 rt.jar、resources.jar达皿、charsets.jar 和 class等天吓。另外需要注意的是可以通過(guò)啟動(dòng)jvm時(shí)指定 -Xbootclasspath 和 路徑 來(lái)改變 Bootstrap ClassLoader 的加載目錄。比如?java -Xbootclasspath/a:path?被指定的文件追加到默認(rèn)的 bootstrap 路徑中峦椰。我們可以打開(kāi)我的電腦龄寞,在上面的目錄下查看,看看這些jar包是不是存在于這個(gè)目錄汤功。

Extention ClassLoader擴(kuò)展的類加載器物邑,加載目錄 %JRE_HOME%\lib\ext 目錄下的jar包和class文件。還可以加載?-D java.ext.dirs?選項(xiàng)指定的目錄滔金。

Appclass Loader也稱為 SystemAppClass?加載當(dāng)前應(yīng)用的classpath的所有類色解。

我們上面簡(jiǎn)單介紹了 3個(gè)ClassLoader。說(shuō)明了它們加載的路徑餐茵。并且還提到了-Xbootclasspath-D java.ext.dirs這兩個(gè)虛擬機(jī)參數(shù)選項(xiàng)科阎。

加載順序

我們看到了系統(tǒng)的3個(gè)類加載器,但我們可能不知道具體哪個(gè)先行呢忿族?我可以先告訴你答案

1. Bootstrap CLassloder

2. Extention ClassLoader

3. AppClassLoader

為了更好的理解萧恕,我們可以查看源碼,sun.misc.Launcher

http://www.grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/sun/misc/Launcher.java

它是一個(gè) java虛擬機(jī) 的入口應(yīng)用:

源碼有精簡(jiǎn)肠阱,我們可以得到相關(guān)的信息。

1.Launcher 初始化了 ExtClassLoader 和 AppClassLoader朴读。

2.Launcher 中并沒(méi)有看見(jiàn) BootstrapClassLoader屹徘,但通過(guò)?System.getProperty("sun.boot.class.path")?得到了字符串?bootClassPath,這個(gè)應(yīng)該就是 BootstrapClassLoader 加載的jar包路徑。

我們可以先代碼測(cè)試一下sun.boot.class.path是什么內(nèi)容衅金。

System.out.println(System.getProperty("sun.boot.class.path"));

得到的結(jié)果是:

可以看到噪伊,這些全是JRE目錄下的jar包或者是class文件簿煌。

ExtClassLoader源碼

如果你有足夠的好奇心,你應(yīng)該會(huì)對(duì)它的源碼感興趣:

我們先前的內(nèi)容有說(shuō)過(guò)鉴吹,可以指定-D java.ext.dirs參數(shù)來(lái)添加和改變 ExtClassLoader 的加載路徑姨伟。這里我們通過(guò)可以編寫(xiě)測(cè)試代碼:

System.out.println(System.getProperty("java.ext.dirs"));

結(jié)果如下:

C:\ProgramFiles\Java\jre1.8.0_91\lib\ext;C:\Windows\Sun\Java\lib\ext

AppClassLoader源碼

可以看到?AppClassLoader 加載的就是java.class.path下的路徑。我們同樣打印它的值:

System.out.println(System.getProperty("java.class.path"));

結(jié)果:

D:\workspace\ClassLoaderDemo\bin

這個(gè)路徑其實(shí)就是當(dāng)前 java工程目錄bin豆励,里面存放的是編譯生成的class文件夺荒。

好了,自此我們已經(jīng)知道了 BootstrapClassLoader良蒸、ExtClassLoader技扼、AppClassLoader 實(shí)際是查閱相應(yīng)的環(huán)境屬性?sun.boot.class.path、java.ext.dirs?和?java.class.path?來(lái)加載資源文件的嫩痰。

接下來(lái)我們探討它們的加載順序剿吻,我們先用 Eclipse 建立一個(gè)java工程:

然后創(chuàng)建一個(gè)Test.java文件:

publicclassTest{}

然后,編寫(xiě)一個(gè)?ClassLoaderTest.java 文件:

我們獲取到了 Test.class 文件的類加載器串纺,然后打印出來(lái)丽旅。結(jié)果是:

ClassLoaderis:sun.misc.Launcher$AppClassLoader@73d16e93

也就是說(shuō)明 Test.class文件 是由 AppClassLoader 加載的。

這個(gè) Test類 是我們自己編寫(xiě)的纺棺,那么 int.class 或者是 String.class 的加載是由誰(shuí)完成的呢托享?我們可以在代碼中嘗試:

運(yùn)行一下,卻報(bào)錯(cuò)了:

提示的是空指針蛀蜜,意思是 int.class 這類基礎(chǔ)類沒(méi)有類加載器加載蹋岩?

當(dāng)然不是!int.class 是由 Bootstrap ClassLoader 加載的杆逗。要想弄明白這些乡翅,我們首先得知道一個(gè)前提。

每個(gè)類加載器都有一個(gè)父加載器

每個(gè)類加載器都有一個(gè)父加載器罪郊,比如加載 Test.class 是由 AppClassLoader 完成蠕蚜,那么 AppClassLoader 也有一個(gè)父加載器,怎么樣獲取呢悔橄?很簡(jiǎn)單靶累,通過(guò) getParent 方法。比如代碼可以這樣編寫(xiě):

運(yùn)行結(jié)果如下:

這個(gè)說(shuō)明癣疟,AppClassLoader 的父加載器是 ExtClassLoader挣柬。那么 ExtClassLoader 的父加載器又是誰(shuí)呢?

運(yùn)行結(jié)果:

又是一個(gè)空指針異常睛挚,這表明 ExtClassLoader 也沒(méi)有父加載器邪蛔。那么,為什么標(biāo)題又是每一個(gè)加載器都有一個(gè)父加載器呢扎狱?這不矛盾嗎侧到?為了解釋這一點(diǎn)勃教,我們還需要看下面的一個(gè)基礎(chǔ)前提。

父加載器不是父類

我們先前已經(jīng)粘貼了 ExtClassLoader 和 AppClassLoader 的代碼:

可以看見(jiàn) ExtClassLoader 和 AppClassLoader 同樣繼承自 URLClassLoader匠抗,但上面一小節(jié)代碼中故源,為什么調(diào)用 AppClassLoader的getParent()?代碼會(huì)得到 ExtClassLoader 的實(shí)例呢?先從 URLClassLoader 說(shuō)起汞贸,這個(gè)類又是什么绳军?先上一張類的繼承關(guān)系圖:

URLClassLoader 的源碼中并沒(méi)有找到?getParent()?方法。這個(gè)方法在 ClassLoader.java 中:

我們可以看到?getParent()?實(shí)際上返回的就是一個(gè) ClassLoader 對(duì)象 parent著蛙,parent 的賦值是在 ClassLoader 對(duì)象的構(gòu)造方法中删铃,它有兩個(gè)情況:

1.由外部類創(chuàng)建 ClassLoader 時(shí)直接指定一個(gè) ClassLoader 為 parent。

2.由?getSystemClassLoader()?方法生成踏堡,也就是在 sun.misc.Laucher 通過(guò)?getClassLoader()?獲取猎唁,也就是 AppClassLoader。直白的說(shuō)顷蟆,一個(gè) ClassLoader 創(chuàng)建時(shí)如果沒(méi)有指定 parent诫隅,那么它的 parent 默認(rèn)就是 AppClassLoader。

我們主要研究的是 ExtClassLoader 與 AppClassLoader 的 parent 的來(lái)源帐偎,正好它們與 Launcher類 有關(guān)逐纬,我們上面已經(jīng)粘貼過(guò) Launcher 的部分代碼。

我們需要注意的是:

代碼已經(jīng)說(shuō)明了問(wèn)題 AppClassLoader 的 paren t是一個(gè) ExtClassLoader 實(shí)例削樊。

ExtClassLoader 并沒(méi)有直接找到對(duì) parent 的賦值豁生。它調(diào)用了它的父類也就是 URLClassLoder 的構(gòu)造方法并傳遞了3個(gè)參數(shù)。

對(duì)應(yīng)的代碼:

答案已經(jīng)很明了了漫贞,ExtClassLoader 的 parent 為null甸箱。

上面張貼這么多代碼也是為了說(shuō)明 AppClassLoader的parent 是 ExtClassLoader,ExtClassLoader 的 parent 是null迅脐。這符合我們之前編寫(xiě)的測(cè)試代碼芍殖。

不過(guò),細(xì)心的同學(xué)發(fā)現(xiàn)谴蔑,還是有疑問(wèn)的我們只看到 ExtClassLoader 和 AppClassLoader 的創(chuàng)建豌骏,那么 BootstrapClassLoader 呢?

還有隐锭,ExtClassLoader 的父加載器為 null,但是 Bootstrap CLassLoader 卻可以當(dāng)成它的父加載器這又是為何呢窃躲?

我們繼續(xù)往下進(jìn)行。

Bootstrap ClassLoader是由C++編寫(xiě)的

Bootstrap ClassLoader 是由C/C++編寫(xiě)的钦睡,它本身是虛擬機(jī)的一部分框舔,所以它并不是一個(gè)JAVA類,也就是無(wú)法在java代碼中獲取它的引用,JVM 啟動(dòng)時(shí)通過(guò) Bootstrap類 加載器加載 rt.jar 等核心jar包中的 class文件刘绣,之前的int.class,String.class都是由它加載。

然后呢挣输,我們前面已經(jīng)分析了纬凤,JVM 初始化 sun.misc.Launcher 并創(chuàng)建 Extension ClassLoader 和 AppClassLoader實(shí)例。并將 ExtClassLoader 設(shè)置為 AppClassLoader 的父加載器撩嚼。Bootstrap 沒(méi)有父加載器停士,但是它卻可以作用一個(gè) ClassLoader 的父加載器。比如 ExtClassLoader完丽。這也可以解釋之前通過(guò) ExtClassLoader 的 getParent方法 獲取為null的現(xiàn)象恋技。具體是什么原因,很快就知道答案了逻族。

雙親委托

我們終于來(lái)到了這一步了蜻底。

一個(gè)類加載器查找 class 和 resource 時(shí),是通過(guò)“委托模式”進(jìn)行的聘鳞,它首先判斷這個(gè)class是不是已經(jīng)加載成功薄辅,如果沒(méi)有的話它并不是自己進(jìn)行查找,而是先通過(guò)父加載器抠璃,然后遞歸下去站楚,直到 Bootstrap ClassLoader,如果 Bootstrap classloader 找到了搏嗡,直接返回窿春,如果沒(méi)有找到,則一級(jí)一級(jí)返回采盒,最后到達(dá)自身去查找這些對(duì)象旧乞。這種機(jī)制就叫做雙親委托

整個(gè)流程可以如下圖所示:

這張圖是用時(shí)序圖畫(huà)出來(lái)的纽甘,不過(guò)畫(huà)出來(lái)的結(jié)果我卻自己都覺(jué)得不理想良蛮。

大家可以看到2根箭頭藍(lán)色的代表類加載器向上委托的方向悍赢,如果當(dāng)前的類加載器沒(méi)有查詢到這個(gè) class對(duì)象 已經(jīng)加載就請(qǐng)求父加載器(不一定是父類)進(jìn)行操作决瞳,然后以此類推。直到 Bootstrap ClassLoader左权。如果 Bootstrap ClassLoader 也沒(méi)有加載過(guò)此class實(shí)例皮胡,那么它就會(huì)從它指定的路徑中去查找,如果查找成功則返回赏迟,如果沒(méi)有查找成功則交給子類加載器屡贺,也就是ExtClassLoader,這樣類似操作直到終點(diǎn),也就是我上圖中的紅色箭頭示例。用序列描述一下:

1.一個(gè) AppClassLoader 查找資源時(shí)甩栈,先看看緩存是否有泻仙,緩存有從緩存中獲取,否則委托給父加載器量没。

2.遞歸玉转,重復(fù)第1部的操作。

3.如果 ExtClassLoader 也沒(méi)有加載過(guò)殴蹄,則由 Bootstrap ClassLoader 出面究抓,它首先查找緩存,如果沒(méi)有找到的話袭灯,就去找自己的規(guī)定的路徑下刺下,也就是?sun.mic.boot.class?下面的路徑。找到就返回稽荧,沒(méi)有找到橘茉,讓子加載器自己去找。

4.Bootstrap ClassLoader 如果沒(méi)有查找成功蛤克,則 ExtClassLoader 自己在?java.ext.dirs?路徑中去查找捺癞,查找成功就返回,查找不成功构挤,再向下讓子加載器找髓介。

5.ExtClassLoader 查找不成功,AppClassLoader 就自己查找筋现,在?java.class.path?路徑下查找唐础。找到就返回。如果沒(méi)有找到就讓子類找矾飞,如果沒(méi)有子類會(huì)怎么樣一膨?拋出各種異常。

上面的序列洒沦,詳細(xì)說(shuō)明了雙親委托的加載流程豹绪。我們可以發(fā)現(xiàn)委托是從下向上,然后具體查找過(guò)程卻是自上至下申眼。

我說(shuō)過(guò)上面用時(shí)序圖畫(huà)的讓自己不滿意瞒津,現(xiàn)在用框圖,最原始的方法再畫(huà)一次:

上面已經(jīng)詳細(xì)介紹了加載過(guò)程括尸,但具體為什么是這樣加載巷蚪,我們還需要了解幾個(gè)個(gè)重要的方法 loadClass()、findLoadedClass()濒翻、findClass()屁柏、defineClass()啦膜。

重要方法

loadClass()

JDK文檔中是這樣寫(xiě)的,通過(guò)指定的全限定類名加載 class淌喻,它通過(guò)同名的 loadClass(String,boolean) 方法:

protectedClassloadClass(Stringname,booleanresolve) throwsClassNotFoundException

上面是方法原型僧家,一般實(shí)現(xiàn)這個(gè)方法的步驟是

1.執(zhí)行?findLoadedClass(String)?去檢測(cè)這個(gè)class是不是已經(jīng)加載過(guò)了。

2.執(zhí)行父加載器的?loadClass方法裸删。如果父加載器為null啸臀,則jvm內(nèi)置的加載器去替代,也就是 Bootstrap ClassLoader烁落。這也解釋了 ExtClassLoader 的 parent 為 null,但仍然說(shuō) Bootstrap ClassLoader 是它的父加載器。

3.如果向上委托父加載器沒(méi)有加載成功豌注,則通過(guò) findClass(String) 查找伤塌。

如果class在上面的步驟中找到了,參數(shù) resolve 又是true的話轧铁,那么 loadClass() 又會(huì)調(diào)用?resolveClass(Class)?這個(gè)方法來(lái)生成最終的Class對(duì)象每聪。 我們可以從源代碼看出這個(gè)步驟:

代碼解釋了雙親委托。要注意的是如果要編寫(xiě)一個(gè) classLoader 的子類齿风,也就是自定義一個(gè) classloader药薯,建議覆蓋?findClass()方法,而不要直接改寫(xiě)?loadClass()方法救斑。另外:

前面說(shuō)過(guò) ExtClassLoader 的 parent 為 null童本,所以它向上委托時(shí),系統(tǒng)會(huì)為它指定 Bootstrap ClassLoader脸候。

自定義ClassLoader

不知道大家有沒(méi)有發(fā)現(xiàn)穷娱,不管是 Bootstrap ClassLoader 還是 ExtClassLoader等,這些類加載器都只是加載指定的目錄下的jar包或者資源运沦。如果在某種情況下泵额,我們需要?jiǎng)討B(tài)加載一些東西呢?比如從D盤(pán)某個(gè)文件夾加載一個(gè)class文件携添,或者從網(wǎng)絡(luò)上下載class主內(nèi)容然后再進(jìn)行加載嫁盲,這樣可以嗎?

如果要這樣做的話烈掠,需要我們自定義一個(gè) classloader羞秤。

自定義步驟

1.編寫(xiě)一個(gè)類繼承自 ClassLoader 抽象類。

2.復(fù)寫(xiě)它的?findClass()?方法向叉。

3.在?findClass()?方法中調(diào)用?defineClass()

defineClass()

這個(gè)方法在編寫(xiě)自定義 classloader 的時(shí)候非常重要锥腻,它能將 class 二進(jìn)制內(nèi)容轉(zhuǎn)換成 Class對(duì)象,如果不符合要求的會(huì)拋出各種異常母谎。

注意點(diǎn)

一個(gè) ClassLoader 創(chuàng)建時(shí)如果沒(méi)有指定 parent瘦黑,那么它的 parent 默認(rèn)就是 AppClassLoader。

上面說(shuō)的是,如果自定義一個(gè) ClassLoader幸斥,默認(rèn)的 parent 父加載器是 AppClassLoader匹摇,因?yàn)檫@樣就能夠保證它能訪問(wèn)系統(tǒng)內(nèi)置加載器加載成功的class文件。

自定義ClassLoader示例之DiskClassLoader

假設(shè)我們需要一個(gè)自定義的classloader,默認(rèn)加載路徑為?D:\lib?下的jar包和資源甲葬。

我們寫(xiě)編寫(xiě)一個(gè)測(cè)試用的類文件廊勃,Test.java:

然后將它編譯過(guò)年class文件Test.class放到D:\lib這個(gè)路徑下。

我們編寫(xiě)DiskClassLoader的代碼:

我們?cè)?findClass()?方法中定義了查找class的方法经窖,然后數(shù)據(jù)通過(guò)?defineClass()?生成了Class對(duì)象坡垫。

現(xiàn)在我們要編寫(xiě)測(cè)試代碼。我們知道如果調(diào)用一個(gè) Test對(duì)象 的 say方法画侣,它會(huì)輸出”Say Hello”這條字符串冰悠。但現(xiàn)在是我們把 Test.class 放置在應(yīng)用工程所有的目錄之外,我們需要加載它配乱,然后執(zhí)行它的方法溉卓。具體效果如何呢?我們編寫(xiě)的 DiskClassLoader 能不能順利完成任務(wù)呢搬泥?我們拭目以待桑寨。

我們點(diǎn)擊運(yùn)行按鈕,結(jié)果顯示:

可以看到忿檩,Test類的say方法正確執(zhí)行尉尾,也就是我們寫(xiě)的 DiskClassLoader 編寫(xiě)成功。

回首

講了這么大的篇幅休溶,自定義ClassLoader才姍姍來(lái)遲代赁。 很多同學(xué)可能覺(jué)得前面有些啰嗦,但我按照自己的思路兽掰,我覺(jué)得還是有必要的芭碍。因?yàn)槲沂菄@一個(gè)關(guān)鍵字進(jìn)行講解的。

關(guān)鍵字是什么孽尽?關(guān)鍵字路徑

從開(kāi)篇的環(huán)境變量

到3個(gè)主要的JDK自帶的類加載器

到自定義的ClassLoader

它們的關(guān)聯(lián)部分就是路徑窖壕,也就是要加載的class或者是資源的路徑。

BootStrap ClassLoader杉女、ExtClassLoader瞻讽、AppClassLoader 都是加載指定路徑下的jar包。如果我們要突破這種限制熏挎,實(shí)現(xiàn)自己某些特殊的需求速勇,我們就得自定義ClassLoader,自已指定加載的路徑坎拐,可以是磁盤(pán)烦磁、內(nèi)存养匈、網(wǎng)絡(luò)或者其它。


完都伪。呕乎。。陨晶。猬仁。。先誉。湿刽。。褐耳。叭爱。。漱病。。把曼。杨帽。。嗤军。注盈。。叙赚。

文章原創(chuàng)作者GuoLin 書(shū)籍推薦

郭林大神原創(chuàng)android 書(shū)籍:《第一行代碼 android》

淘寶鏈接: https://s.click.taobao.com/t?e=m%3D2%26s%3DgKUfuKdAZKocQipKwQzePOeEDrYVVa64K7Vc7tFgwiHjf2vlNIV67p2n%2BQBNMyE6Rku8%2Bpj6eJall3bs%2B3NRhNHnsKI%2BqxhyM0iVZhTFBom4YIorMPnmg8G0g2OJi%2FzmXHfenomYtn5EW9vzeG8LzfPUwktUBEmkxg5p7bh%2BFbQ%3D&pvid=10_106.6.161.154_3367_1490163222155

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末老客,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子震叮,更是在濱河造成了極大的恐慌胧砰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苇瓣,死亡現(xiàn)場(chǎng)離奇詭異尉间,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)击罪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)哲嘲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人媳禁,你說(shuō)我怎么就攤上這事眠副。” “怎么了竣稽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵囱怕,是天一觀的道長(zhǎng)霍弹。 經(jīng)常有香客問(wèn)我,道長(zhǎng)光涂,這世上最難降的妖魔是什么庞萍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮忘闻,結(jié)果婚禮上钝计,老公的妹妹穿的比我還像新娘。我一直安慰自己齐佳,他們只是感情好私恬,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著炼吴,像睡著了一般本鸣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上硅蹦,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天荣德,我揣著相機(jī)與錄音,去河邊找鬼童芹。 笑死涮瞻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的假褪。 我是一名探鬼主播署咽,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼生音!你這毒婦竟也來(lái)了宁否?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缀遍,失蹤者是張志新(化名)和其女友劉穎慕匠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體域醇,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡絮重,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歹苦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片青伤。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖殴瘦,靈堂內(nèi)的尸體忽然破棺而出狠角,到底是詐尸還是另有隱情,我是刑警寧澤蚪腋,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布丰歌,位于F島的核電站姨蟋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏立帖。R本人自食惡果不足惜眼溶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晓勇。 院中可真熱鬧堂飞,春花似錦、人聲如沸绑咱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)描融。三九已至铝噩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窿克,已是汗流浹背骏庸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留年叮,地道東北人敞恋。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像谋右,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子补箍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容