JavaWeb學習之——ClassLoader

概述

在java中,ClassLoader負責把一個java類加載進Java虛擬機。爲了防止重複加載和安全性方便的考慮,ClassLoader是具備層次結構的。java

1.ClassLoader類

ClassLoader的主要方法包括:git

1.1 defineClass

protected final Class<?> defineClass(String name, byte[] b, int off, int len)
        throws ClassFormatError
    {
        return defineClass(name, b, off, len, null);
    }

經過defineClass是將byte數組轉換爲JVM可以識別的對象,能夠看出,字節數組能夠來自本地,網絡等途徑web

1.2 findLoadedClass

protected final Class<?> findLoadedClass(String name) {
        if (!checkName(name))
            return null;
        return findLoadedClass0(name);
    }

經過類的全名來加載一個類數組

1.3 loadClass

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // 首先檢查class是否已經加載
            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) {
                    // 當父classLoader沒有加載的成功的時候拋出異常
                }

                if (c == null) {
                    // 若是還還加載成功,試圖調用findClass來加載類
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // 記錄狀態
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

能夠看出,加載類的時候都是先從父類中加載安全

1.3 findClass

protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }

findClass默認是沒有任何實現的,只是拋出異常,所以咱們能夠覆蓋該方法, 重寫咱們本身的類加載途徑java-web

代碼例子:怎麼使用classLoader加載自定義byte數組並經過反射調用其中方法網絡

https://git.oschina.net/null_584_3382/java-web-example/tree/masterspa

2. ClassLoader等級加載機制

從文章前面的描述中,能夠看出 class loader在加載類的時候,優先是從其父加載器中加載,而且每一個Class Loader 都有一個字段指向其父加載器(若是沒有指定默認爲AppClassLoader).net

ClassLoader的層次結構:code

上面的圖是隨便找的,下面簡單介紹一下

2.1 BootStrap ClassLoader

這個類是爲JVM本身服務的,加載JVM自身工做所須要的類,這個類徹底是由JVM本身控制的。該類其實並不遵照前面所規定的等級加載制度。這個類即沒有父加載器,也沒有子加載器。

2.2 ExtClassLoader 

這個加載器主要用於加載 java.ext.dirs目錄下的類,也算是一種特殊的類加載器,他是往上能追溯到的最高加載器

2.3 AppClassLoader

這個類就是專門爲咱們使用的,他的父加載器ExtClassLoader ,全部在ClassPath下的類都由他加載(前提你沒有定義其餘本身的ClassLoader)。咱們本身實現的ClassLoader的父加載器就是這個類。

ExtClassLoader 和AppClassLoader都是Launch的內部類,都繼承URLClassLoader,而URLClassLoader又繼承ClassLoader。

2.4 java加載ClassLoader 的方式

第一種方式是隱式加載方式,加載一個類的時候,若是他的父類沒有加載,就會先加載其父類(順帶說一句,本身實現ClassLoader 的時候,也要準守先從父加載器中加載,否則加載到Java.xxx 的類的時候,就會提示報錯,由於 java.xxx 的類是不容許從其餘地方加載的)

第二種方式是顯示加載,也就是咱們本身顯示使用loadClass方法加載

// TODO

相關文章
相關標籤/搜索