Java基礎----Classloader加載機制

1、Java虛擬機JVM加載類的機制:默認提供三種類加載器

  本文中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
2、BootstrapClassLoader、ExtClassLoader、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中的雙親委託機制;

相關文章
相關標籤/搜索