ClassLoader關鍵在于
加載 -> 連結(驗證+準備+解析) -> 初始化(使用前的準備) -> 使用 -> 解除安裝
可以隻加載,不連結
ClassLoader.loadClass(className)
ClassLoader.loadClass(className,false)
也可以加載,并連結
Class.forName(className)
Class.forName(className,true,classloader);
判斷一個類是否已經被加載 (隻加載,不連結)
public static boolean isPresent(String name) {
try {
Thread.currentThread().getContextClassLoader().loadClass(name);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
一 Java類裝載過程
裝載:通過類的全限定名擷取二進制位元組流,将二進制位元組流轉換成方法區中的運作時資料結構,在記憶體(堆)中生成Java.lang.Class類對象;
連結:執行下面的校驗、準備和解析步驟,其中解析步驟是可以選擇的;
校驗:檢查導入類或接口的二進制資料的正确性;(檔案格式驗證,中繼資料驗證,位元組碼驗證,符号引用驗證)
準備:給類的靜态變量配置設定并初始化存儲空間; (預設初始化)
解析:将常量池中的符号引用轉成直接引用;
初始化:激活類的靜态變量的初始化和靜态Java代碼塊的執行,并初始化程式員設定的變量值。
二 分析 Class.forName()和ClassLoader.loadClass
Class.forName(className)方法,内部實際調用的方法是 Class.forName(className,true,classloader);
第2個boolean參數表示類是否需要初始化, Class.forName(className)預設是需要初始化。
一旦初始化,就會觸發目标對象的 static塊代碼執行,static參數也也會被再次初始化。
ClassLoader.loadClass(className)方法,内部實際調用的方法是 ClassLoader.loadClass(className,false);
第2個 boolean參數,表示目标對象是否進行連結,false表示不進行連結,由上面介紹可以,
不進行連結意味着不進行包括初始化等一些列步驟,那麼靜态塊和靜态對象就不會得到執行。
consult :
https://blog.csdn.net/x_iya/rticle/details/73199280
https://www.cnblogs.com/yunger/p/5760444.html