双亲委派机制

77 阅读2分钟

我正在参加「掘金·启航计划」

jvm对class文件加载采用的是按需加载,只有使用到或者关联到的类才会加载到内存中生成class模板对象,而jvm加载机制使用的是双亲委派机制,即通过委托模式交由父类加载器执行。

什么是双亲委派机制?

如果一个类加载器收到了类加载的请求,他并不会由当前类直接加载,而是先交给自己的父类加载器去执行加载,如果父类加载器还存在父类加载器那么继续交由父类加载器执行加载, 一直递归直到类加载器不存在父类加载器,如果父类加载器执行成功则返回成功,如果父类加载器执行失败或者没有父类加载器则由当前类加载器执行类的加载。

image.png

如上图可以看到classLoader类加载器的loadClass方法这里会先去判断当前parent是否为空不为空则调用父类的loadClass方法,而parent父类加载器也是ClassLoader对象,如下图

image.png

为什么要有双亲委派机制?

1.为了防止不同类加载器多次加载同一个class文件产生多个class对象

2.保证程序安全 这里我在根目录下创建一个包java.lang目录,在新建一个String类,编写一个static静态代码块,里面输出一句话,如果我们自定义的String类被初始化那么就会输出,如下图:

image.png

新建一个test测试类,注意不能在刚刚的java.lang包下否则不能加载通过,因为java.lang包是java的核心类库目录,没权限访问,会抛出异常,如下图:

image.png

另外目录执行测试代码如下图:

image.png

可以发现被没有输出自定义String类里的static静态代码块的语句,说明自定义String类并没有被加载到,为什么呢?明明是指定了java.lang.String()自定义对象String的,原因就是在加载我们的的业务代码之前,引导类加载器(Bootstrap ClassLoader)已经将java的核心类库加载完成了,其中String已经存在了所以我们引用的就是java的String了。可以试想一下,如果不是这样那么我们可以肆意的去创建这种java的核心类很可能会导致jvm安全受到威胁。