JVM 類加載器常用的三種方式
1. 默認(rèn)方式 之雙親委托模式
子類加載器在加載一個(gè)類時(shí)庶溶,會(huì)讓父類先加載秘症。如果父類已經(jīng)加載了的時(shí)候匪凉,沒有必要讓子類再加載一次捌肴。
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先蹬叭,檢查從JVM緩存查找該類
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) { // 然后委托給父類加載器進(jìn)行加載
c = parent.loadClass(name, false);
} else { // 如果父類加載器為null, 則委托給Bootstrap類加載器加載
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// 如果仍然沒有找到,則調(diào)用findClass()進(jìn)行查找
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;
}
}
從以上代碼可知哭靖,實(shí)現(xiàn)自己的類加載策略可以覆蓋ClassLoader的findClass() 或者loadClass()方法來實(shí)現(xiàn)具垫。
2. 父類加載器加載子類加載器中的資源
如果一個(gè)類引用了另一個(gè)類,那么被引用的類應(yīng)該有引用方類加載器加載试幽。
通過設(shè)置和獲取線程上下文類加載器ContextClassLoader實(shí)現(xiàn)
ClassLoader extClassLoader = MyContextClassLoad.class.getClassLoader().getParent();
Thread.currentThread().setContextClassLoader(extClassLoader);
3. 類加載器要使用不在當(dāng)前類加載器查找路徑的類
新建一個(gè)在指定路徑查找類的類加載器