双亲委派机制
Posted strandtrack
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双亲委派机制相关的知识,希望对你有一定的参考价值。
工作原理:
1.如果一个类加载器收到了类加载请求,他并不会自己先去加载,而是把这个请求委托给父类加载器去执行
2.如果父类加载器还存在其父类加载器,则进一步向上委托,一次递归,请求最终将到达顶层的启动类加载器
3.如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载
这就是双亲委派机制的概念。但是提到双亲委派机制不得不提到类加载器的概念(ClassLoader)。
java是运行在Java的虚拟机(JVM)中的,但是它是如何运行在JVM中了呢?我们在IDE中编写的Java源代码被编译器编译成.class的字节码文件。然后由我们得ClassLoader负责将这些class文件给加载到JVM中去执行。
JVM分为两类类加载器,分别为引导类加载器(bootstrapClassLoader)和自定义类加载器。
为什么这样分呢?因为引导类加载器,也可以叫启动类加载器是c语言,c++写的,不是ClassLoader类派生的,而其他的都是java写的,都属于ClassLoader派生的。
其他是什么呢?
JVM也可以分为四种类加载器:
1.启动类加载器(BootStrap ClassLoader):
用来加载java的核心库,只加载包名为java,javax,sun等开头的类。
2.扩展类加载器(Extension ClassLoader):
父类加载器为启动类加载器,派生于ClassLoader类。也就是这个调用getParent()得到的是null,也就是启动类加载器(因为是c实现的,所以显示null)。只在jre/lib/ext子目录下加载类库。
3.应用程序加载器(AppClassLoader):
父类加载器为扩展类加载器,负责加载java.class.path下的类库。
4.用户自定义类加载器
现在用例子来讲解一下双亲委派机制:
假设我自己定义一个类,全包名是java.lang.String,也就是和Java提供的String同名,这个时候我来调用new String(),这个类调用的是我自定义的类还是java给的类呢?
答案是java给的类,这就是双亲委派机制的作用了,当我调用时,用的应用程序加载器会先去找它的父类加载器->扩展类加载器,扩展类加载器再去找它的父类->引导类加载器,引导类加载器没有父类,所以这时候看自己能否解决,一看包名,java.lang ,java归他管啊,所以他就自己解决了,把Java提供的string加载进来,所以调用的就不是我自定义的类了。
如果还不能理解的话,举个现实生活中的例子:
你有了一根鸡腿,你要先问问你妈吃不吃,孝敬长辈嘛,然后你妈再问你奶奶吃不吃。如果你奶奶能吃的话,她就吃了,你和你妈就在一边看着流口水就行了。
但是如果你奶奶说太油腻了我不吃,然后给你妈妈,你妈说馊了,我不吃,再给你,这时候你就可以吃了!
这就是双亲委派机制!!
双亲委派机制的优势
- 避免类的重复加载
- 保护程序安全,防止核心API被随意篡改
- 自定义类:java.lang.String
- 自定义类:java.lang.MeDsh(java.lang包需要访问权限,阻止我们用包名自定义类)
以上是关于双亲委派机制的主要内容,如果未能解决你的问题,请参考以下文章