自定义类加载器继承ClassLoader类,使用自定义类加载器是通过loadClass方法实现。
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // 查找类是否已经加载
Class c = findLoadedClass(name);
if (c == null) {
try { if (parent != null) { //存在父类,先委托父类进行加载
c = parent.loadClass(name, false);
} else { /*没有父类,则委托引导类加载器,委托机制是出于安全考虑,详细可见《深入java虚拟机第二版》,这个loadClass方法没有用到final修饰符,也就是用户可以重载它,不需要用这个委托机制?*/
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) { // findClass自定义加载器会重写这个方法
c = findClass(name);
}
if (resolve) { //对类进行解析
resolveClass(c);
}
return c;
}
上面的finaLoadedClass方法会调用到share/vm/prims/jvm.cpp的JVM_FindLoadedClass方法,
JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)) {
.......
klassOop k = SystemDictionary::find_instance_or_array_klass(klass_name, h_loader, Handle(), CHECK_NULL);
}
上面会调用到
klassOop SystemDictionary::find(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS) {
unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader);
int d_index = dictionary()->hash_to_index(d_hash);
{
No_Safepoint_Verifier nosafepoint;
return dictionary()->find(d_index, d_hash, class_name, class_loader,protection_domain, THREAD);/*这个方法根据类名、类加载器及访问权限来查找这个类是否已经加载,同一个类如果是两个类加载器加载,在虚拟机里面会存在两个对象。*/
}
}