核心方法:html
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