- 類加載 咱們都知道,JVM裏通常有多個類加載器:
- 啓動類加載器(加載rt.jar,且只負責這個範圍,避免用戶本身定義一個java.lang.Object類並加載),此類加載器沒法被Java程序直接引用。
- 擴展類加載器 (加載 JAVA_HOME/lib/ext目錄中的jar) ,能夠直接使用。
- 應用程序類加載器 (負責加載ClassPath路徑的類),經過ClassLoader.getSystemClassLoader()返回引用。
- 自定義的類加載器。
- JVM中類加載的順序:若是一個類加載器收到了類加載請求,它先是把加載請求委派給父類加載器去完成,依次遞歸到啓動類加載器。。。因此全部的加載請求最終都會傳送到啓動類加載器中去,但不必定會由啓動類加載器完成加載(好比加載com.ali.Dog)。只有當父加載器沒法完成該加載請求時(類加載器負責加載的範圍找不到),子加載器纔會去嘗試加載。這個加載模型也稱爲「雙親委派加載模型」。
- 自定義類加載器 咱們爲何須要自定義的類加載器?答:當你開發一個框架工具時,極可能要加載框架中的某些類。
- 如何定義本身的類加載器?首先你本身定義的類加載器,也要符合「雙親委派加載模型」。其次,你要理解ClassLoader類中的方法,推薦看源碼。
- ClassLoader中的構造
- loadClass(String name, boolean resolve),第二個參數:是否在加載時linking。(鏈接是類加載步驟中的一步,是初始化的必要條件。即:類初始化了,一定通過鏈接。。而鏈接了,未必初始化了),補充一下類加載的流程:加載 -> (驗證 -> 準備 -> 解析) -> 初始化 -> 使用 ->卸載。(驗證 -> 準備 -> 解析 三個步驟合稱鏈接),此方法的實現:a.查找是否加載過name類 b.若是沒有加載過且有父加載器,則讓父加載器去加載,若是沒有父類加載器,則直接使用啓動類加載器加載name類。c.若是通過上述兩步,尚未加載到類name,那麼再調用findClass(name)方法,此方法的ClassLoader類實現是拋出異常。。因此當你自定義一個類加載時,要複寫該方法。
- defineClass(String name, byte[] b, int off, int len)方法,是用你本身類加載器實現「加載」這個動做的主要方法,我的感受,你確定不會真正的用C語言實現一下類加載的過程,無非是調用已有的「加載」方法。
- 《深刻理解Java虛擬機》 P228的代碼demo分析,待續。。。有些困了,回頭繼續
[IBM wiki-Java虛擬機加載(https://www.ibm.com/developerworks/cn/java/j-lo-classloader/)java