介紹
雙親委派模型要求除了頂層的啟動類加載器外科盛,其余的類加載器都應(yīng)當(dāng)有自己的父類加載器滔吠。一般使用組合(Copmposition)關(guān)系來服用父類加載的代
工作過程
如果一個類加載器收到了類加載的請求庞萍,它首先不會自己嘗試加載這個類惹苗,而是把這個請求委派給父類加載器去完成套耕,因此所有的加載請求最終都應(yīng)該傳到頂層的啟動類加載器中构灸,只有當(dāng)父類加載器反饋?zhàn)约簾o法完成加載請求時件已,子加載器才會嘗試自己去加載笋额。
源碼分析
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
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) {
}
if (c == null) {
// 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;
}
}
雙親委派模型對于保證Java進(jìn)程的穩(wěn)定運(yùn)作很重要,但它的實(shí)現(xiàn)卻非常簡單篷扩,源代碼都集中在java.lang.ClassLoader的loadClass()方法中兄猩,邏輯清晰易懂:先檢查是否已經(jīng)被加載過,若沒有加載則調(diào)用父加載器的loadClass方法鉴未,若父加載器為空則默認(rèn)使用啟動類加載作為父加載器厦滤。如果父類加載失敗,拋出ClassNotFoundException異常后歼狼,在調(diào)用自己的findzClass()方法進(jìn)行加載