ClassLoader類加載器是負責加載類的對象。ClassLoader 類是一個抽象類。若是給定類的二進制名稱(即爲包名加類名的全稱),那麼類加載器會試圖查找或生成構成類定義的數據。通常策略是將名稱轉換爲某個文件名,而後從文件系統讀取該名稱的「類文件」。java.lang.ClassLoader類的基本職責就是根據一個指定的類的名稱,找到或者生成其對應的字節代碼,而後從這些字節代碼中定義出一個 Java 類,即 java.lang.Class類的一個實例。除此以外,ClassLoader還負責加載 Java 應用所需的資源,如圖像文件和配置文件等。 做爲全部類加載器的基類,ClassLoader的內部實現機制仍是值得咱們細細研究一下的。因此今天我就帶領你們一塊兒來看一下Classloader的內部實現源碼。java
首先咱們來看一下Classloader類的兩個構造方法。c++
從上邊的幫助文檔中咱們能夠發現,在建立一個classloader的實例時咱們能夠顯示的指出他的父加載器,也能夠不指定,不指定的時候他的默認的父加載器是系統加載器。咱們來看一下源碼的實現:this
/** * Creates a new class loader using the <tt>ClassLoader</tt> returned by * the method {@link #getSystemClassLoader() * <tt>getSystemClassLoader()</tt>} as the parent class loader. */ protected ClassLoader() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkCreateClassLoader(); } this.parent = getSystemClassLoader(); initialized = true; }
/** * Creates a new class loader using the specified parent class loader for */ protected ClassLoader(ClassLoader parent) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkCreateClassLoader(); } this.parent = parent; initialized = true; }
從上面源碼咱們能夠發現,classloader中必定有一個parent的屬性來指定當前loader的附加器。其源碼也證實了咱們剛纔上面的說法。spa
看完構造方法的實現,下一步咱們來看一下ClassLoader中一個特別重要的方法loadclass方法,這個方法就是用來加載類的。這個方法在jdk中有個重載的方法,可是實際上是一個樣的。一個帶有是否連接類的方法,一個不帶。下面咱們就看一下這個方法的源碼:code
public Class<?> loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); } /** * Loads the class with the specified <a href="#name">binary name</a>. The * default implementation of this method searches for classes in the * @throws ClassNotFoundException * If the class could not be found */ 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 = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }
關於這個方法的源碼解釋,我感受我不必解釋什麼,由於在API中已經有詳細的解釋了。我在解釋確定也不如他解釋的好,因此咱們來看一下API是怎麼解釋的吧:對象
雖然jdk已經解釋的很清楚了,可是有一點我仍是要在補充一下。從上面的源碼咱們能夠看出loadClass方法是一個遞歸的方法,一直往上找,一直找到根類加載器爲止,而後讓類加載器去加載這個類。至於跟加載器是怎麼實現的咱們就不得而知了。由於跟類加載加載類時一個本地方法,他是用c++寫的。咱們沒法看到他的源碼。這樣驗證了在前面咱們所說的類加載器的父類委託機制。遞歸
下面咱們來看一下findClass方法,咱們在上面的代碼中發現。在loadClass方法中有調用這個findclass方法,下面咱們首先來看一下API對這個方法的介紹:ssl
從上面介紹咱們能夠看出,這個方法主要是來查找咱們的類文件的。咱們在自定義咱們本身的類加載器的時候應該重寫這個方法,由於jdk中對這個方法基本沒有實現什麼,這就須要咱們本身來重寫這個方法,用咱們本身的所定義的方法去查找類文件。不信。你能夠看一下他的源碼實現:ci
protected Class<?> findClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(name); }
暫時先介紹這些吧。其餘的方法基本都差很少,最近感受博客愈來愈難寫,愈來愈吃力。愈來愈發現底層理論的缺少。但願經過本身的努力,能夠慢慢改變這個現狀。資源