本文中JDK安裝目錄爲:E:\Java\jdk1.7.0_60html
一、Bootstrap classloader 根類加載器,使用系統本地語言編寫,沒法獲取到;主要負責加載位於JDK安裝目錄 Java\jdk1.7.0_60\jre\lib下的類,好比rt.jar,其中包括java
sun.misc.Launcher、ExtClassLoader、AppClassLoader
Launcher.class 官方網站找不到只能使用反編譯工具JD-GUI,進行反編譯;apache
public class ClassLoaderTest { public static void main(String[] args) { sun.misc.URLClassPath path = sun.misc.Launcher.getBootstrapClassPath(); for (URL url : path.getURLs()) { System.out.println(url.toString()); } } }
file:/E:/Java/jdk1.7.0_60/jre/lib/resources.jar file:/E:/Java/jdk1.7.0_60/jre/lib/rt.jar file:/E:/Java/jdk1.7.0_60/jre/lib/sunrsasign.jar file:/E:/Java/jdk1.7.0_60/jre/lib/jsse.jar file:/E:/Java/jdk1.7.0_60/jre/lib/jce.jar file:/E:/Java/jdk1.7.0_60/jre/lib/charsets.jar file:/E:/Java/jdk1.7.0_60/jre/lib/jfr.jar file:/E:/Java/jdk1.7.0_60/jre/classes
二、ExtClassLoader 擴展類加載器 ,負責加載 E:\Java\jdk1.7.0_60\jre\lib\extbootstrap
三、AppClassLoader 系統類加載器 ,負責加載項目中classpath 下的類,主要包括項目中引入的第三方類庫和本身編寫的類;
工具
import org.apache.logging.log4j.Logger; public class ClassLoaderTest { public static void main(String[] args) { ClassLoader loader = ClassLoaderTest.class.getClassLoader(); System.out.println("本身編寫的類的類加載器---"+loader.getClass().getName()); ClassLoader thirdClassLoader = Logger.class.getClassLoader(); System.out.println("第三方日誌類庫org.apache.logging.log4j.Logger的類加載器---"+thirdClassLoader.getClass().getName()); } }
運行結果:網站
本身編寫的類的類加載器---sun.misc.Launcher$AppClassLoader 第三方日誌類庫org.apache.logging.log4j.Logger的類加載器---sun.misc.Launcher$AppClassLoader
1.AppClassLoader類中有一個引用指向ExtClassLoader ;ExtClassLoader類中也有一個引用指向BootstrapClassLoader,因爲BootstrapClassLoader是系統本地語言編寫,沒法用Java獲取,全部引用爲nullthis
public static void main(String[] args) { ClassLoader loader = ClassLoaderTest.class.getClassLoader(); System.out.println("AppClassLoder---"+loader.getClass().getName()); ClassLoader parentLoader = loader.getParent(); System.out.println("AppClassLoder parent---"+parentLoader.getClass().getName()); ClassLoader bootstrapLoader = parentLoader.getParent(); System.out.println("ExtClassLoader parent---"+bootstrapLoader); }
AppClassLoder---sun.misc.Launcher$AppClassLoader AppClassLoder parent---sun.misc.Launcher$ExtClassLoader ExtClassLoader parent---null
二、AppClassLoader和ExtClassLoader 都繼承自URLClassLoader url
URLClassLoader 繼承自SecureClassLoader
spa
SecureClassLoader繼承自ClassLoader日誌
三、類加載的過程:自底向上,其中AppClassLoader 和ExtClassLoader 的loadClass方法都是調用父類的
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded 檢查是否加載過 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(); 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; } }
a、首先 AppClassLoader 查找是否已經加載過,若是找到了,直接返回Class;
b、若是沒有找到,找上一級類加載器ExtClassLoader查找,若是找到了,直接返回Class;
c、若是沒有找到由BootStrapClassLoader 進行加載,加載成功直接返回Class;
d、若是沒有加載成功,由下一級ExtClassLoader負責加載,加載成功直接返回Class;
e、若是沒有加載成功,由下一級AppClassLoader負責加載,加載成功直接返回Class;
f、若是沒有加載成功,拋出異常ClassNotFoundException;
以上就是Java中的雙親委託機制;