首頁 > 遊戲

面試官:Class.forName 和 ClassLoader.loadClass 有什麼區別?

由 當代程式設計師 發表于 遊戲2023-01-06

簡介getCallerClass() 方法獲取類載入器來載入類public static Class forName(String name, boolean initialize,ClassLoader loader)throws Class

asi loader是什麼

面試官:Class.forName 和 ClassLoader.loadClass 有什麼區別?

Class。forName 和 ClassLoader。loadClass 都可以用來反射載入一個類,主要有2種區別:

1 使用的類載入器不一樣

Class。forName 最終是使用呼叫方的 ClassLoader 來載入類,在程式碼中使用 Reflection。getCallerClass() 方法獲取類載入器來載入類

public static Class<?> forName(String name, boolean initialize,

ClassLoader loader)

throws ClassNotFoundException

{

Class<?> caller = null;

SecurityManager sm = System。getSecurityManager();

if (sm != null) {

caller = Reflection。getCallerClass();

if (sun。misc。VM。isSystemDomainLoader(loader)) {

// 使用呼叫方的 ClassLoad 載入類

ClassLoader ccl = ClassLoader。getClassLoader(caller);

if (!sun。misc。VM。isSystemDomainLoader(ccl)) {

sm。checkPermission(

SecurityConstants。GET_CLASSLOADER_PERMISSION);

}

}

}

return forName0(name, initialize, loader, caller);

}

ClassLoader。loadClass 遵循類載入的雙親委派模型類載入類,在程式碼中使用 ClassLoader parent 載入類

// The parent class loader for delegation

if (parent != null) {

c = parent。loadClass(name, false);

}

雙親委託模型:當一個類載入器接收到一個類載入的任務時,不會立即展開載入,而是將載入任務委託給它的父類載入器去執行,每一層的類都採用相同的方式,直至委託給最頂層的啟動類載入器為止。如果父類載入器無法載入委託給它的類,便將類的載入任務退回給下一級類載入器去執行載入。

2 類的裝載過程不一樣

類的裝載過程為:

連結

|

————————————————

載入 ——> | 驗證 ——> 準備 ——> 解析| ——> 初始化 ——> 使用 ——> 解除安裝

————————————————

Class。forName 會裝載類到初始化階段,因此會執行類中的靜態方法塊,呼叫 forName0 時傳入的 initialize 為 true

public static Class<?> forName(String className)

throws ClassNotFoundException {

Class<?> caller = Reflection。getCallerClass();

// initialize = true

return forName0(className, true, ClassLoader。getClassLoader(caller), caller);

}

ClassLoader。loadClass 會裝載類到載入節點,不會執行連結操作,因此不會執行類中的靜態方法塊,在程式碼中呼叫 loadClass 時傳入的 resolve 為 false,表示不連結類

if (parent != null) {

// resolve = false

c = parent。loadClass(name, false);

}

如:

class Test {

static {

System。out。print(“loaded”);

}

}

使用 Class。forName 載入 Test 類會輸出 “loaded”,而使用 ClassLoader。loadClass 載入則不會輸出 “loaded”

Tags:載入ClassLoaderclassloadClasscaller