而jvm内置的class loader有3种,分别是 Bootstrap ClassLoader, Extension ClassLoader(即ExtClassLoader),System ClassLoader(即AppClassLoader).
而jvm加载时的双亲委派 就不说了,javaeye上有很多文章都有介绍..
可以分别看一下他们的构造器,其中Bootstrap ClassLoader是用c写的.
java.lang.ClassLoader
protected ClassLoader(ClassLoader parent) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkCreateClassLoader(); } //给父loader赋值. this.parent = parent; initialized = true; } protected ClassLoader() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkCreateClassLoader(); } //这边将会把AppClassLoader付给父loader this.parent = getSystemClassLoader(); initialized = true; }
这个构造器有带参数的,和不带构造器的2个。带参数的构造器传入的是这个 class loader的父loader,而不带参数的构造器则会把getSystemClassLoader()所返回的class loader当作他自己的父装载器.下面我们来看getSystemClassLoader()的代码
public static ClassLoader getSystemClassLoader() { //所返回的class loader在这个方法里面被赋值 initSystemClassLoader(); if (scl == null) { return null; } SecurityManager sm = System.getSecurityManager(); if (sm != null) { ClassLoader ccl = getCallerClassLoader(); if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) { sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); } } return scl; } private static synchronized void initSystemClassLoader() { if (!sclSet) { if (scl != null) throw new IllegalStateException("recursive invocation"); sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); if (l != null) { Throwable oops = null; //在这边被赋值 scl = l.getClassLoader(); ................................... ....................................... } } sclSet = true; } }
这边的父class loader就是scl,也就是l.getClassLoader()所得到的,getClassLoader(),接下来看Launcher的源码:
private static Launcher launcher = new Launcher(); public static Launcher getLauncher() { return launcher; } private ClassLoader loader; public Launcher() { // Create the extension class loader ClassLoader extcl; try { //这里传入构造器的parent为空 extcl = ExtClassLoader.getExtClassLoader(); } catch (IOException e) { throw new InternalError( "Could not create extension class loader"); } // Now create the class loader to use to launch the application try { //这边可以看到默认的loader就是AppClassLoader,也就是说getSystemClassLoader返回的就是AppClassLoader loader = AppClassLoader.getAppClassLoader(extcl); } catch (IOException e) { throw new InternalError( "Could not create application class loader"); } //每一个当前线程一个classload,以防止多线程中的classload引起的混乱(这个是我自己理解的,呵呵) // Also set the context class loader for the primordial thread. Thread.currentThread().setContextClassLoader(loader); ................................... ................................................ } /* * Returns the class loader used to launch the main application. */ public ClassLoader getClassLoader() { return loader; }
从中我们看到AppClassLoader的父loader是ExtClassLoader,而ExtClassLoader的父loader是什么呢?我们在来看ExtClassLoader的构造器:
public ExtClassLoader(File[] dirs) throws IOException { super(getExtURLs(dirs), null, factory); this.dirs = dirs; }他的父loader为空,而他的顶级父类是java.lang.ClassLoader而当传入的parent为null时,我们使用 ExtClassLoader load一个类时,系统会调用Bootstrap ClassLoader.
protected synchronized Class> loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { //先调用父loader来load. c = parent.loadClass(name, false); } else { //调用Bootstrap ClassLoader来load c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }
而这里findBootstrapClass0也就是调用Bootstrap ClassLoader这个最核心的class loader来load class.
最终我们可以看到getSystemClassLoader() 返回的class loader就是AppClassLoader.