常見類加載器:BootstrapClassLoader/ExtClassLoader/AppClassLoader/URLClassLoader/WebappClassLoader。html
BootstrapClassLoader(啓動類加載器):主要加載JVM自身工做須要的類,徹底由JVM本身控制;它是全部類加載器的父加載器,位於jre/lib/rt.jar。java
ExtClassLoader(擴展類加載器):它既裝載除了基本的Java API之外的擴展類,也負責裝載其餘的安全擴展功能;位於System.getProperty("java.ext.dirs")指向的目錄。bootstrap
AppClassLoader(系統類加載器):負責加載用戶在$CLASSPATH裏指定的類,位於System.getProperty("java.class.path")。安全
User-defined ClassLoader(用戶自定義類加載器):直接用代碼實現的類加載器,如:WebappClassLoader。app
類是如何被加載的? 它們使用雙親委派的模型來加載;基於三個機制:委託、可見性和單一性。this
委託:當一個類加載和初始化的時候,類僅在有須要加載的時候被加載。首先加載這個類的請求由AppClassLoader委託給它的父類加載器ExtClassLoader,而後再委託給BootstrapClassLoader。BootstrapClassLoader會先看看rt.jar中有沒有這個類,若是並無這個類,就把這個請求返回到ExtClassLoader,它會查看jre/lib/ext目錄下有沒有這個類,若是這個類被ExtClassLoader找到了,那麼它將被加載,而AppClassLoader不會加載這個類;而若是這個類沒有被ExtClassLoader找到,那麼再由AppClassLoader從classpath中尋找。spa
可見性:子類加載器能夠看到父類加載器加載的類,而反之則不行。.net
單一性:父加載器加載過的類不能被子加載器加載第二次。htm
class的加載方式?對象
隱式加載:不經過調用ClassLoader來加載須要的類,而是經過JVM自動加載所需的類到內存。如,繼承與類引用。
顯示加載:經過ClassLoader類來加載類的方式。如,this.getClass().getClassLoader().loadClass()/Class.forName()/自定義的類加載器的findClass()。
Class.forName(),ClassLoader.loadClass()的區別
http://blog.csdn.net/qq_27093465/article/details/52262340
自定義類加載器?
本身定義的類加載器通常繼承ClassLoader/URLClassLoader。
通常只須要重寫findClass()方法;
同一個類若是被兩個類加載器加載,那麼JVM不認爲使相同的類;
檢查被請求的類是否已經被加載到命名空間,若是已被加載,則直接返回。
若是想打破雙親委派模型,那麼就重寫整個loadClass方法
https://www.cnblogs.com/szlbm/p/5504631.html
JDK中的ClassLoader實現的:
先先查找.class是否被加載過,若是.class文件沒有被加載過,那麼會去找加載器的父加載器。
父加載器開始嘗試加載.class文件,加載成功就返回一個java.lang.Class,加載不成功就拋出一個ClassNotFoundException,給子加載器去加載。
雙親委派機制
一、類的加載過程採用委託模式實現
二、每一個 ClassLoader 都有一個父加載器。
三、類加載器在加載類以前會先遞歸的去嘗試使用父加載器加載。
四、虛擬機有一個內建的啓動類加載器(bootstrap ClassLoader),該加載器沒有父加載器,可是能夠做爲其餘加載器的父加載器。
雙親委派機制能很好地解決類加載的統一性問題。
JVM在斷定兩個class是否相同時,不只要判斷兩個類名是否相同,並且要判斷是否由同一個類加載器實例加載的。只有二者同時知足的狀況下,JVM才認爲這兩個class是相同的。
對一個 Class 對象來講,若是類加載器不一樣,即使是同一個字節碼文件,生成的 Class 對象也是不等的。也就是說,類加載器至關於 Class 對象的一個命名空間。
雙親委派機制則保證了基類都由相同的類加載器加載,這樣就避免了同一個字節碼文件被屢次加載生成不一樣的 Class 對象的問題。
但雙親委派機制僅僅是Java 規範所推薦的一種實現方式,它並非強制性的要求。近年來,不少熱部署的技術都已不遵循這一規則,如 OSGi 技術就採用了一種網狀的結構,而非雙親委派機制。
http://www.cnblogs.com/paddix/p/5268559.html
classloader加載一個類的過程分爲4步:
第一步,從某個地方獲得咱們想要的字節碼二進制流;
第二步,讀入字節碼流並轉化爲Class;
第三步,連接;
第四步,初始化。
ClassLoader 提供了另外一個方法 findClass 來完成第一步,
而後調用ClassLoader提供的defineClass來完成第二步,
ClassLoader提供了resolveClass方法完成第三步連接的工做
https://mp.weixin.qq.com/s/qHTXwS4BdI2gKwPzQK-D6g
Class.forName和ClassLoader.loadClass區別:
第一,ClassLoader.loadClass能夠顯式指定裝載class的ClassLoader,可是Class.forName就不行了,他會默認使用調用類的ClassLoader來裝載class。
第二,ClassLoader.loadClass僅僅加載class進來,可是不會初始化類,而Class.forName不只會加載class並且還會初始化類。
https://blog.csdn.net/liweisnake/article/details/8857744
https://blog.csdn.net/u011202334/article/details/51497998
http://blog.csdn.net/xyang81/article/details/7292380#10006-weixin-1-52626-6b3bffd01fdde4900130bc5a2751b6d1