Java 类加载的双亲委派机制
双亲委派机制
Java 中存在 3 种类型的类加载器:
- 引导类加载器
- 扩展类加载器
- 系统类加载器
三者是的关系是:引导类加载器是扩展类加载器的父类,扩展类加载器是系统类加载器的父类。
启动类加载器(BootStrap)
主要负责加载 JVM 自身所需要的类,该加载器由 C++ 实现,加载的是<JAVA_HOME>/lib
下的 class 文件,或-Xbootclasspath
参数指定的路径下的jar包加载到内存中,注意必由于虚拟机是按照文件名识别加载jar包的,如rt.jar
,如果文件名不被虚拟机识别,即使把jar包丢到 lib 目录下也是没有作用的(出于安全考虑,Bootstrap 启动类加载器只加载包名为 java、javax、sun 等开头的类)。
标准拓展类加载器(ExtClassLoader)
扩展类加载器是指Sun公司实现的sun.misc.Launcher$ExtClassLoader
类,由 Java 语言实现的,是 Launcher 的静态内部类,它负责加载<JAVA_HOME>/lib/ext
目录下或者由系统变量-Djava.ext.dir
指定位路径中的类库,开发者可以直接使用标准扩展类加载器。
java源码 在 sun.misc.Launcher
|
|
系统类加载器(AppClassLoader)
也称应用程序加载器是指 Sun公司实现的sun.misc.Launcher$AppClassLoader
。它负责加载系统类路径java -classpath
或-D java.class.path
指定路径下的类库,也就是我们经常用到的 classpath 路径,开发者可以直接使用系统类加载器,一般情况下该类加载是程序中默认的类加载器,通过ClassLoade.getSystemClassLoader()
方法可以获取到该类加载器。
|
|
在 Java 的日常应用程序开发中,类的加载几乎是由上述3种类加载器相互配合执行的,在必要时,我们还可以自定义类加载器,需要注意的是,Java 虚拟机对 class 文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的 class 文件加载到内存生成 class 对象,而且加载某个类的 class 文件时,Java 虚拟机采用的是双亲委派模式即把请求交由父类处理,它一种任务委派模式。
流程分析
双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器。每个类加载器都是如此,只有在父类加载器在自己的搜索范围内找不到指定类时,子类加载器才会尝试自己去加载。
双亲委派模型工作工程:
例子:
当一个Hello.class这样的文件要被加载时。不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理会先检查自己是否已经加载过,如果没有再往上。注意这个过程,直到到达Bootstrap classLoader之前,都是没有哪个加载器自己选择加载的。如果父加载器无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。
目的
首先明确一点:jvm如何认定两个对象同属于一个类型,必须同时满足下面两个条件:
- 都是用同名的类完成实例化的。
- 两个实例各自对应的同名的类的加载器必须是同一个。比如两个相同名字的类,一个是用系统加载器加载的,一个扩展类加载器加载的,两个类生成的对象将被jvm认定为不同类型的对象。
所以,为了系统类的安全,类似java.lang.Object
这种核心类,JVM 需要保证他们生成的对象都会被认定为同一种类型。即**“通过代理模式,对于 Java 核心库的类的加载工作由引导类加载器来统一完成,保证了 Java 应用所使用的都是同一个版本的 Java 核心库的类,是互相兼容的”**。
为了不让我们写 System 类,类加载采用委托机制,这样可以保证爸爸们优先,爸爸们能找到的类,儿子就没有机会加载。而 System 类是 Bootstrap 加载器加载的,就算自己重写,也总是使用 Java 系统提供的System,自己写的 System 类根本没有机会得到加载。
- 原文作者:范明勇
- 原文链接:https://blog.fanmuyong.com/post/Java-%E7%B1%BB%E5%8A%A0%E8%BD%BD%E7%9A%84%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%9C%BA%E5%88%B6/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。