Java類的加載機制

什么是類的加載?

類的加載指的是將類的.class文件中的二進制數(shù)據(jù)讀入內(nèi)存中,將其放在運行時數(shù)據(jù)區(qū)域的方法去內(nèi),然后在堆中創(chuàng)建java.lang.Class對象,用來封裝類在方法區(qū)的數(shù)據(jù)結(jié)構(gòu).只有java虛擬機才會創(chuàng)建class對象,并且是一一對應(yīng)關(guān)系.這樣才能通過反射找到相應(yīng)的類信息.

我們上面提到過Class這個類,這個類我們并沒有new過,這個類是由java虛擬機創(chuàng)建的。通過它可以找到類的信息,我們來看下源碼:

/*
     * Private constructor. Only the Java Virtual Machine creates Class objects.
     * This constructor is not used and prevents the default constructor being
     * generated.
     */
    private Class(ClassLoader loader) {
        // Initialize final field for classLoader.  The initialization value of non-null
        // prevents future JIT optimizations from assuming this final field is null.
        classLoader = loader;
    }

從上面貼出的Class類的構(gòu)造方法源碼中,我們知道這個構(gòu)造器是私有的,并且只有虛擬機才能創(chuàng)建這個類的對象。

類加載器

什么是類加載器?

類加載器負(fù)責(zé)對類的加載。

Java自帶有3種類加載器

    1)根類加載器,使用c++編寫(BootStrap),負(fù)責(zé)加載rt.jar
    2)擴展類加載器,java實現(xiàn)(ExtClassLoader)  JRE/lib/ext/*.jar
    3)應(yīng)用加載器,java實現(xiàn)(AppClassLoader) classpath  

根類加載器,是用c++實現(xiàn)的,我們沒有辦法在java層面看到;而ExtClassLoader和AppClassLoader的代碼,它是在sun.misc.Launcher類中,

static class ExtClassLoader extends URLClassLoader  
static class AppClassLoader extends URLClassLoader

雙親委派機制

關(guān)于類加載器,我們不得不說一下雙親委派機制。聽著很高大上,其實很簡單。比如A類的加載器是AppClassLoader(其實我們自己寫的類的加載器都是AppClassLoader),AppClassLoader不會自己去加載類,而會委ExtClassLoader進行加載,那么到了ExtClassLoader類加載器的時候,它也不會自己去加載,而是委托BootStrap類加載器進行加載,就這樣一層一層往上委托,如果Bootstrap類加載器無法進行加載的話,再一層層往下走。

java.lang.ClassLoader的loadClass方法很清楚地告訴了我們這一點:

private final ClassLoader parent;
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;
        }
    }

從上面代碼我們知道首先會檢查class是否已經(jīng)加載了,如果已經(jīng)加載那就直接拿出,否則再進行加載。其中有一個parent屬性,就是表示父加載器。這點正好說明了加載器之間的關(guān)系并不是繼承關(guān)系。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、什么是類的加載機制 類的加載指的是將類的.class文件中的二進制數(shù)據(jù)讀入到內(nèi)存中,將其放在運行時數(shù)據(jù)...
    huststl閱讀 428評論 0 1
  • 1、什么是類的加載 類的加載指的是將類的.class文件中的二進制數(shù)據(jù)讀入到內(nèi)存中,將其放在運行時數(shù)據(jù)區(qū)的方法區(qū)內(nèi)...
    Java_Explorer閱讀 346評論 0 2
  • 聲明:原創(chuàng)文章,轉(zhuǎn)載請注明出處。http://www.itdecent.cn/u/e02df63eaa87 1、什...
    唐影若凡閱讀 562評論 0 4
  • 2018-10-03 推薦原文 原文 什么是類的加載 類的加載指的是將類的.class文件中的二進制數(shù)據(jù)讀入到內(nèi)存...
    vsu閱讀 303評論 0 0
  • 首先聲明,我是因為看了ImportNew網(wǎng)站上的幾篇關(guān)于類加載器的文章之后,才萌生了寫這篇文章的想法。所以在寫這篇...
    陳安妮annie1閱讀 310評論 0 1

友情鏈接更多精彩內(nèi)容