Java类加载器和双亲委派机制

前言

之前详细介绍了Java类的整个加载过程(类加载机制详解)。虽然,篇幅较长,但是也不要被内容吓到了,其实每个阶段都可以用一句话来概括。

1)加载:查找并加载类的二进制字节流数据。

2)验证:保证被加载的类的正确性。

3)准备:为类的静态变量分配内存,并设置默认初始值。

4)解析:把类中的符号引用转换为直接引用。

5)初始化:为类的静态变量赋予正确的初始值。

当然,要想掌握类加载机制,还是需要去深入研究的。(好吧,说了一句正确的废话)因为其中,有很多知识点也是面试中常问的。比如,我之前去面试的时候,面试官就问到了一个和类初始化相关的问题。就是给一段代码,有父子类关系,父子类中包含静态代码块、构造代码块、普通代码块、构造函数等,然后让判断代码最终的执行顺序。(可自行思考一下,具体内容细节暂时不做扩展)

类加载器

终于来到了本文的主题 —— 类加载器和双亲委派机制。

在《深入理解Java虚拟机》中,对于类加载器的定义是这样的:

虚拟机设计团队把类加载阶段中的“通过一个类的权限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。

简单来说,类加载器的作用就是去加载class类的二进制字节流的。

类加载器有以下三种:

1)启动类加载器(Bootstrap ClassLoader),或者叫根加载器。这个类加载器主要是去加载你在本机配置的环境变量 Java_Home/jre/lib 目录下的核心API,如rt.jar

file

2)扩展类加载器(Extension ClassLoader)。这个加载器负责加载 Java_Home/jre/lib/ext 目录下的所有jar包。

3)应用程序类加载器(Application ClassLoader)。这个加载器加载的是你的项目工程的ClassPath目录下的类库。如果用户没有自定义自己的类加载器,这个就是程序默认的类加载器。

另外,如果有需要的话,用户也可以自定义自己的类加载器(去继承ClassLoader类)。

我们也可以通过代码把类加载器打印出来:

public class TestClassLoader {
    public static void main(String[] args) {
        Object obj = new Object();
        System.out.println(obj.getClass().getClassLoader());

        TestClassLoader t = new TestClassLoader();
        System.out.println(t.getClass().getClassLoader());
        System.out.println(t.getClass().getClassLoader().getParent());
        System.out.println(t.getClass().getClassLoader().getParent().getParent());
    }
}

打印结果:

null
sun.misc.Launcher$AppClassLoader@58644d46
sun.misc.Launcher$ExtClassLoader@6d6f6e28
null

注意,上面第一行和第四行的null此处可不是空的意思,它代表的是启动类加载器。因为启动类加载器是用C++代码来实现的,严格来说不属于Java类,所以Java代码访问不到,故返回null。第二行是应用程序类加载器,第三行是扩展类加载器。

双亲委派机制

在介绍双亲委派机制之前,先观察一下以下代码能否正确运行:

//自己定义的一个 java.lang包
package java.lang;

public class String {
    public static void main(String[] args) {
        String s = new String();
        System.out.println(s);
    }
}

以上代码,编译没有任何问题,但是运行时,却报错:

file

为什么提示在java.lang.String类中找不到main方法呢,我这明明不是定义了吗?其实,问题的关键就在于类加载遵循双亲委派机制。

类加载器有以下这样的层次关系:

file

当一个类在加载的时候,都会先委派它的父加载器去加载,这样一层层的向上委派,直到最顶层的启动类加载器。如果顶层无法加载(即找不到对应的类),就会一层层的向下查找,直到找到为止。 这就是类的双亲委派机制。

这样做有什么好处呢?这就相当于维护了一个有优先级的层级关系,即总是从最顶层的父加载器开始加载。这就如同,你工作中遇到了问题需要向上反馈,比如先反馈给小组长,然后小组长反馈给上级经理,最后经理反馈给boss。然后boss感觉这问题太简单了不需要他亲自出手,让经理自己解决吧,然后经理又向下交给小组长。小组长一看,这问题不算难,人也比较热心,于是就帮你把问题解决了。(可能例子不是太恰当哈,意思理解即可)

到此,我们就明白了为什么上边的代码会报错。因为双亲委派机制的存在,去加载我们自己定义的“java.lang.String”类的时候,会最终委派到顶层的启动类加载器,然后找到了rt.jar包下的“java.lang.String”。找到之后,就直接加载rt.jar包的String类(也就是我们经常使用的那个字符串类),不再去向下查找,也就加载不了我们自定义的String类了。由于,rt.jar包下的String类中确实没有main方法,所以才会有以上的报错信息。

我们可以试想一下,如果没有双亲委派机制的存在,那我这段代码是不是就可以执行成功了。如果这样的话,岂不是说明我可以随意覆盖rt.jar包中的类(如String,Integer类等)。这样的话将会使程序陷入混乱,Java核心包中的类的安全也无法保证。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,192评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,858评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,517评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,148评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,162评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,905评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,537评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,439评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,956评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,083评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,218评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,899评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,565评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,093评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,201评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,539评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,215评论 2 358

推荐阅读更多精彩内容