五分鐘看懂ClassLoader

ava.lang.ClassLoader類概述:

從文檔中對ClassLoader類的介紹能夠總結出這個類的做用就是根據一個指定的類的全限定名,找到對應的Class字節碼文件,而後加載它轉化成一個java.lang.Class類的一個實例.java

類加載器的劃分:

啓動類加載器(Bootstrap ClassLoader):bash

 這個類加載器負責將<JAVA_HOME>\lib目錄下的類庫加載到虛擬機內存中,用來加載java的核心庫,此類加載器並不繼承於java.lang.ClassLoader,不能被java程序直接調用,代碼是使用C++編寫的.是虛擬機自身的一部分.post

擴展類加載器(Extendsion ClassLoader):
 這個類加載器負責加載<JAVA_HOME>\lib\ext目錄下的類庫,用來加載java的擴展庫,開發者能夠直接使用這個類加載器.
spa

應用程序類加載器(Application ClassLoader):code

這個類加載器負責加載用戶類路徑(CLASSPATH)下的類庫,通常咱們編寫的java類都是由這個類加載器加載,這個類加載器是CLassLoader中的getSystemClassLoader()方法的返回值,因此也稱爲系統類加載器.通常狀況下這就是系統默認的類加載器.cdn

除此以外,咱們還能夠加入本身定義的類加載器,以知足特殊的需求,須要繼承java.lang.ClassLoader類.對象

  類加載器之間的層次關係以下圖:

使用代碼觀察一下類加載器:

package com.wang.test;

public class TestClassLoader {

    public static void main(String[] args) {
        ClassLoader loader = TestClassLoader.class.getClassLoader();
        System.out.println(loader.toString());
        System.out.println(loader.getParent().toString());
        System.out.println(loader.getParent().getParent());
    }
}複製代碼

觀察打印結果:blog

sun.misc.Launcher$AppClassLoader@500c05c2
sun.misc.Launcher$ExtClassLoader@454e2c9c
null繼承

第一行打印的是應用程序類加載器(默認加載器),第二行打印的是其父類加載器,擴展類加載器,按照咱們的想法第三行應該打印啓動類加載器的,這裏卻返回的null,緣由是getParent(),返回時null的話,就默認使用啓動類加載器做爲父加載器.內存

類加載器的雙親委派模型:

雙親委派模型是一種組織類加載器之間關係的一種規範,他的工做原理是:若是一個類加載器收到了類加載的請求,它不會本身去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,這樣層層遞進,最終全部的加載請求都被傳到最頂層的啓動類加載器中,只有當父類加載器沒法完成這個加載請求(它的搜索範圍內沒有找到所需的類)時,纔會交給子類加載器去嘗試加載.

這樣的好處是:java類隨着它的類加載器一塊兒具有了帶有優先級的層次關係.這是十分必要的,好比java.langObject,它存放在\jre\lib\rt.jar中,它是全部java類的父類,所以不管哪一個類加載都要加載這個類,最終全部的加載請求都彙總到頂層的啓動類加載器中,所以Object類會由啓動類加載器來加載,因此加載的都是同一個類,若是不使用雙親委派模型,由各個類加載器自行去加載的話,系統中就會出現不止一個Object類,應用程序就會全亂了.

Class.forname()與ClassLoader.loadClass():

Class.forname():是一個靜態方法,最經常使用的是Class.forname(String className);根據傳入的類的全限定名返回一個Class對象.該方法在將Class文件加載到內存的同時,會執行類的初始化.

如: Class.forName(「com.wang.HelloWorld」);

ClassLoader.loadClass():這是一個實例方法,須要一個ClassLoader對象來調用該方法,該方法將Class文件加載到內存時,並不會執行類的初始化,直到這個類第一次使用時才進行初始化.該方法由於須要獲得一個ClassLoader對象,因此能夠根據須要指定使用哪一個類加載器.

如:ClassLoader cl=…….;cl.loadClass(「com.wang.HelloWorld」);

相關文章
相關標籤/搜索