六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 60|回复: 0

java的ClassLoader

[复制链接]

升级  98%

57

主题

57

主题

57

主题

秀才

Rank: 2

积分
197
 楼主| 发表于 2013-1-27 05:44:07 | 显示全部楼层 |阅读模式
java有两种类型的classload,一种是user-defined的,一种是jvm内置的bootstrap class loader,所有user-defined的class loader都是java.lang.ClassLoader的子类.

而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付给父loaderthis.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 loaderClassLoader 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 applicationtry {//这边可以看到默认的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 loadedClass 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.
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表