URLClassLoader
对于AppClassLoader和ExtClassLoader而言,这两个类是继承了URLClassLoader这个类,而URLClassLoader这个类是继承了SecureClassLoader,之后这个SecureClassLoader是继承了ClassLoader这个抽象类
AppClassLoader和ExtClassLoader继承URLClassLoader有一个重要的一环,是在URLClassLoader中重写了findClass这个方法,使得这两个类在进行本类进行加载的过程中可以执行类的加载过程。而SecureClassLoaders是用于安全校验的,对于用户来说用处不大。这个URLClassLoader主要是用来协助实际的类加载器完成加载,因为补充了findClass,完善了类的实际加载过程。
public Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
int i = name.lastIndexOf('.');
if (i != -1) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPackageAccess(name.substring(0, i));
}
}
if (ucp.knownToNotExist(name)) {
// The class of the given name is not found in the parent
// class loader as well as its local URLClassPath.
// Check if this class has already been defined dynamically;
// if so, return the loaded class; otherwise, skip the parent
// delegation and findClass.
Class<?> c = findLoadedClass(name);
if (c != null) {
if (resolve) {
resolveClass(c);
}
return c;
}
throw newClassNotFoundException(name);
}
return (super.loadClass(name, resolve));
}
上面的是AppClassLoader关于loadClass的重写,发现其实,并没干什么,还是用的classLoader类的loadClass方法进行加载。
主动使用和被动使用
Class.forName()
调用的方法是会使类进行加载链接初始化全过程的。可以通过类的具体描述可以看出来,同时可以进去看源码
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
会发现,initialize这个参数是true的。
classLoader.loadClass
classLoader.loadClass方法是不负责类的初始化的,甚至都不会进行解析,可以看以下源码
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
可以看出,resolve这个字段被赋值为false。