1、雙親委派機制及作用
1.1 什麼是雙親委派機制
當某個類載入器需要載入某個.class
檔案時,它首先把這個任務委託給他的上級類載入器,遞迴這個操作,如果上級的類載入器沒有載入,自己才會去載入這個類。
1.2 類載入器的類別
BootstrapClassLoader(啟動類載入器)
c++
編寫,載入java
核心庫 java.*
,構造ExtClassLoader
和AppClassLoader
。由於引導類載入器涉及到虛擬機器本地實現細節,開發者無法直接獲取到啟動類載入器的引用,所以不允許直接通過引用進行操作
ExtClassLoader (標準擴充套件類載入器)
java
編寫,載入擴充套件庫,如classpath
中的jre
,javax.*
或者
java.ext.dir
指定位置中的類,開發者可以直接使用標準擴充套件類載入器。
AppClassLoader(系統類載入器)
java`編寫,載入程式所在的目錄,如`user.dir`所在的位置的`class
CustomClassLoader(使用者自定義類載入器)
java
編寫,使用者自定義的類載入器,可載入指定路徑的class
檔案
1.3 原始碼分析
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先檢查這個classsh是否已經載入過了
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
// c==null表示沒有載入,如果有父類的載入器則讓父類載入器載入
if (parent != null) {
c = parent.loadClass(name, false);
} else {
//如果父類的載入器為空 則說明遞迴到bootStrapClassloader了
//bootStrapClassloader比較特殊無法通過get獲取
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {}
if (c == null) {
//如果bootstrapClassLoader 仍然沒有載入過,則遞迴回來,嘗試自己去載入class
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.4 委派機制的流程圖
1.5 雙親委派機制的作用
1、防止重複載入同一個.class
。通過委託去向上面問一問,載入過了,就不用再載入一遍。保證資料安全。
2、保證核心.class
不能被篡改。通過委託方式,不會去篡改核心.clas
,即使篡改也不會去載入,即使載入也不會是同一個.class
物件了。不同的載入器載入同一個.class
也不是同一個Class
物件。這樣保證了Class
執行安全。