核心方法:
protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
//自上往下检查类是否已经被加载
Class c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
//双亲委派加载
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
//双亲加载没有找到,则继续检查其他类加载器是否加载过
//自定义类加载器加载
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
//findClass需要Override
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
JVM启动时产生三个类加载器:Bootstrap ClassLoader,Extension ClassLoader,App ClassLoader。Bootstrap ClassLoader负责加载核心类库(jdk lib下的类),用C++实现,java代码中显示为null;Extension ClassLoader负责加载lib/ext下的类;App ClassLoader负责加载ClassPath下的类。其中Bootstrap ClassLoader是Extention ClassLoader的父加载器,Extention ClassLoader是APP ClassLoader的父加载器,但不是父子类关系。
由源代码可见双亲委托机制在加载类时类似递归先回溯到Bootstrap ClassLoader,再Extension ClassLoader,再App ClassLoader......此机制一个重要原因是安全原因:防止不安全类的加载进来,比如重新实现String类Boolean类等,加载时回溯到Bootstrap ClassLoader会发现已经加载过了,在不会加载自定义的String类取代掉JDK String。判断两个类是不是同一个类,除了名字相同还要是加载器类相同才可以。
参考
http://www.cnblogs.com/kabi/p/5198961.html
http://www.cnblogs.com/kabi/p/5198788.html