本篇文章僅僅只是對ClassLoader類的loadClass方法從源碼上進(jìn)行分析,至于跟類加載相關(guān)的雙親委托模式等其他知識點(diǎn),不做介紹與闡述,因為網(wǎng)上大把介紹這些的文章,而且我不認(rèn)為自己能寫得比他們好
接下來又是跟之前的兩篇一樣,直接貼相關(guān)的源代碼啦~/(≧▽≦)/~
public abstract class ClassLoader { PRivate static native void registerNatives(); static { registerNatives(); } private final ClassLoader parent; /** * ClassLoader類中的靜態(tài)內(nèi)部類,他可以決定指定的類是否具備并行的能力, * 若具備并行能力則ClassLoader下面的parallelLockMap便會被初始化, * 該靜態(tài)內(nèi)部類在ClassLoader被加載的時候便被初始化了 */ private static class ParallelLoaders { private ParallelLoaders() {} //存放具備并行能力的加載器類型的Set集合 private static final Set<Class<? extends ClassLoader>> loaderTypes = Collections.newSetFromMap( new WeakHashMap<Class<? extends ClassLoader>, Boolean>()); static { synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); } } /** * 將指定的類加載器注冊成為一個具備并行能力的類加載器,注冊成功則返回true,否則返回false */ static boolean register(Class<? extends ClassLoader> c) { synchronized (loaderTypes) { //只有當(dāng)該類加載器的父類具備并行能力時,該類加載器方可成功注冊 if (loaderTypes.contains(c.getSuperclass())) { loaderTypes.add(c); return true; } else { return false; } } } /** * 判斷指定的classloader類加載器是否具備并行的能力 */ static boolean isRegistered(Class<? extends ClassLoader> c) { synchronized (loaderTypes) { return loaderTypes.contains(c); } } } //若當(dāng)前類加載器具備并行能力,則該屬性會被初始化 private final ConcurrentHashMap<String, Object> parallelLockMap; /** * ClassLoader類的構(gòu)造函數(shù),在這里主要確定該類加載器是 * 否具備并行能力與其他變量的初始化操作 * @param unused * @param parent */ private ClassLoader(Void unused, ClassLoader parent) { this.parent = parent; //若該類加載器具備并行能力(如何判斷見ClassLoader類中的靜態(tài)內(nèi)部類) if (ParallelLoaders.isRegistered(this.getClass())) { //初始化parallelLockMap parallelLockMap = new ConcurrentHashMap<>(); package2certs = new ConcurrentHashMap<>(); domains = Collections.synchronizedSet(new HashSet<ProtectionDomain>()); assertionLock = new Object(); } else { //不具備并行能力,parallelLockMap置為null parallelLockMap = null; package2certs = new Hashtable<>(); domains = new HashSet<>(); assertionLock = this; } } public Class<?> loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); } /** * 使用指定的二進(jìn)制名稱來加載類,這個方法的默認(rèn)實現(xiàn)按照以下順序查找類:調(diào)用findLoadedClass(String)方法 * 檢查這個類是否被加載過,使用父加載器調(diào)用loadClass(String)方法,如果父加載器為Null,類加載器裝載虛擬機(jī) * 內(nèi)置的加載器調(diào)用findClass(String)方法裝載類,如果按照以上的步驟成功的找到對應(yīng)的類,并且該方法接收的resolve * 參數(shù)的值為true,那么就調(diào)用resolveClass(Class)方法來處理類,ClassLoader的子類最好覆蓋findClass(String)而不是 * 這個方法,除非被重寫,這個方法默認(rèn)在整個裝載過程中都是同步的(線程安全的) */ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { //這里根據(jù)當(dāng)前類加載器是否具備并行能力而獲取對應(yīng)的鎖對象 synchronized (getClassLoadingLock(name)) { /** * 在加載類之前先調(diào)用findLoadClass方法查找看該類是否加載過, * 若被加載過則直接返回該對象,無需二次加載,未加載過則返回null, * 進(jìn)行下一個流程 * PS:ClassLoader類中的findLoaderClass方法是一個本地方法, * 自定義的類加載器需要重寫該方法 */ Class c = findLoadedClass(name); //若該類未被加載過 if (c == null) { long t0 = System.nanoTime(); try { //如果父類加載器不為空,則調(diào)用父類加載器的loadClass方法加載 if (parent != null) { c = parent.loadClass(name, false); } else { //若父類加載器為空,則調(diào)用虛擬機(jī)的加載器Bootstrap ClassLoader來加載類 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) {} //若以上的操作都沒有成功加載到類 if (c == null) { long t1 = System.nanoTime(); //則調(diào)用該類自己的findClass方法來加載類 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) { //這個方法用來給ClassLoader鏈接一個類(具體干嘛我不知道額) resolveClass(c); } return c; } } /** * 這個方法是根據(jù)當(dāng)前類加載器是否具備并行能力而決定是否返回鎖對象, * 當(dāng)該類加載器不具備并行能力,則無需返回一個加鎖對象,若具備并行能 * 力,則返回一個新的加鎖對象 */ protected Object getClassLoadingLock(String className) { Object lock = this; //根據(jù)parallelLockMap是否被初始化來判斷當(dāng)前類加載器是否具備并行能力 if (parallelLockMap != null) { //若該類加載器具備并行能力,則創(chuàng)建新的鎖對象返回 Object newLock = new Object(); lock = parallelLockMap.putIfAbsent(className, newLock); if (lock == null) { lock = newLock; } } return lock; }}這里推薦自己覺得挺不錯的一篇介紹類加載原理的博文http://blog.csdn.net/xyang81/article/details/7292380完畢了額~~~銘記初衷,傾己所有
新聞熱點(diǎn)
疑難解答
圖片精選