實現自定義 classLoader
每個自定義載入器必須直接或間接擴充套件 java.lang.ClassLoader
類。主要的擴充套件點是以下方法:
findClass(String)
- 如果類載入器遵循類載入的標準委託模型,則過載此方法。loadClass(String, boolean)
- 過載此方法以實現替代委派模型。findResource
和findResources
- 過載這些方法以自定義資源載入。
負責從位元組陣列中實際載入類的 defineClass
方法是 final
以防止過載。在呼叫 defineClass
之前,需要執行任何自定義行為。
這是一個從位元組陣列載入特定類的簡單:
public class ByteArrayClassLoader extends ClassLoader {
private String classname;
private byte[] classfile;
public ByteArrayClassLoader(String classname, byte[] classfile) {
this.classname = classname;
this.classfile = classfile.clone();
}
@Override
protected Class findClass(String classname) throws ClassNotFoundException {
if (classname.equals(this.classname)) {
return defineClass(classname, classfile, 0, classfile.length);
} else {
throw new ClassNotFoundException(classname);
}
}
}
由於我們只重寫了 findClass
方法,所以當呼叫 loadClass
時,這個自定義類載入器將表現如下。
- 類載入器的
loadClass
方法呼叫findLoadedClass
來檢視此類載入器是否已載入具有此名稱的類。如果成功,則生成的Class
物件將返回給請求者。 - 然後
loadClass
方法通過呼叫loadClass
呼叫委託給父類載入器。如果父程序可以處理請求,它將返回一個Class
物件,然後將該物件返回給請求者。 - 如果父類載入器無法載入類,則
findClass
會呼叫我們的覆蓋findClass
方法,傳遞要載入的類的名稱。 - 如果請求的名稱與
this.classname
匹配,我們呼叫defineClass
從this.classfile
位元組陣列載入實際的類。然後返回生成的Class
物件。 - 如果名稱不匹配,我們扔
ClassNotFoundException
。