核心方法:html
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { //自上往下檢查類是否已經被加載 Class c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { //雙親委派加載 if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } //雙親加載沒有找到,則繼續檢查其餘類加載器是否加載過 //自定義類加載器加載 if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); //findClass須要Override c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
JVM啓動時產生三個類加載器:Bootstrap ClassLoader,Extension ClassLoader,App ClassLoader。Bootstrap ClassLoader負責加載核心類庫(jdk lib下的類),用C++實現,java代碼中顯示爲null;Extension ClassLoader負責加載lib/ext下的類;App ClassLoader負責加載ClassPath下的類。其中Bootstrap ClassLoader是Extention ClassLoader的父加載器,Extention ClassLoader是APP ClassLoader的父加載器,但不是父子類關係。 由源代碼可見雙親委託機制在加載類時相似遞歸先回溯到Bootstrap ClassLoader,再Extension ClassLoader,再App ClassLoader......此機制一個重要緣由是安全緣由:防止不安全類的加載進來,好比從新實現String類Boolean類等,加載時回溯到Bootstrap ClassLoader會發現已經加載過了,在不會加載自定義的String類取代掉JDK String。判斷兩個類是否是同一個類,除了名字相同還要是加載器類相同才能夠。 參考 http://www.cnblogs.com/kabi/p/5198961.html http://www.cnblogs.com/kabi/p/5198788.html