在编程领域,很多名词都非常奇怪,这就非常容易造成软件工程师不少困惑与不解,就像java中的类加载机制,网上成篇大论都谈到一个名词-----双亲委派机制,下面就是类加载的最关键代码。

protected 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) {
                    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.
                c = findClass(name);
            }
        }
        return c;
}

看到上面的代码,我会想双亲是谁?委派又从何而来?中文虽然博大精深,但是要将双亲委派和这段代码联系起来,未免太牵强。

这段代码我用一个例子来说明:

一、儿子在家找身份证,先看了看自己周围有没有,如果没有,就打电话找他爸问问。

二、儿子发现他周围没有,然后打电话问他爸爸,说爸爸,看见我的身份证了吗?

三、爸爸在他自己周边找了一圈,没有发现,爸爸就打电话给了爷爷。

四、爷爷在他边上翻找了一圈,也没有发现,爷爷觉得这可不行,我得仔细找找,爷爷去自己的房间找了一圈没有发现,他就只能和孙子的爸爸说没找到。

五、无奈的爸爸只能去他自己的房间找了一圈,最终也没找到,他就训斥孩子,身份证是你自己的,又不是别人的,你自己想办法。

六、儿子无奈地回了房间,发现身份证就在他自己的房间。

这个故事虽然有点假,但是已经将java类加载机制通过叙事的手段说清楚了。

儿子就是AppClassLoader. 爸爸就是ExtClassLoader 爷爷就是BootStrapClassLoader

身份证就是要加载的类,儿子的周边就是他自己的缓存空间,儿子的房间是属于他管理类加载路径

爸爸的周边就是爸爸的缓存空间,爸爸的房间是属于爸爸所管理的类加载路径

爷爷的周边就是爷爷的缓存空间,爷爷的房间是属于爷爷所管理的类加载路径

这个故事核心就是找东西,至于怎么找,先找离自己最近范围的,没有就打电话给亲人,让他们帮忙找找,最后这么一圈下来,如果最终都没找到,就报一个类未找到异常,故事中找的是儿子的身份证,那多半是在儿子自己的生活圈中,但是儿子记不清了,就像程序一样,谁都不知道哪些类是谁加载的一样。

如果是爷爷的身份证,那就好比java中的String类一样,属于爷爷的生活范围,也只有爷爷能找到,爸爸和儿子不可能找得到,假如爷爷的东西都是非常贵重的,就像java中的核心包一样。如果有人要弄个赝品给到儿子手里,依照这个流程,只要爷爷手中的是真的,那这个赝品不会被找到,因为爷爷优先查找。

所以java类加载机制---双亲委托机制这个说法站不住脚,但是我也没能找到一个很好的词汇来描述这套机制,因为它和我们的生活不太一样,所以我只能以上面的一个故事来讲明白这套机制。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注