一、类加载器概述
加载类时会先询问上级:这个类是否加载过了;如果没有,还会再委托上级查看有无加载过这个类。
只有上级两个加载器都没有加载过,才会轮到应用程序类加载器加载。
——双亲委派的类加载模式:
先由下到上询问,后由上到下加载
-
启动类加载器
可以用一些虚拟机参数,将自己编写的参数交给启动类加载器加载。
启动类加载器是由cpp程序编写的。(了解)
AppClassLoader ExtClassLoader NULL(没找到加载器 也就是启动类加载器)
-
扩展类加载器
二、双亲委派模式
from javaguide
每一个类都有一个对应它的类加载器。系统中的 ClassLoader 在协同工作的时候会默认使用 双亲委派模型 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。加载的时候,首先会把该请求委派给父类加载器的 loadClass() 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader 中。当父类加载器无法处理时,才由自己来处理。当父类加载器为 null 时,会使用启动类加载器 BootstrapClassLoader 作为父类加载器。
所谓双亲委派,就是指调用类加载器的loadClass方法时,查找类的规则。
通俗地说:上级没有加载,才由本级的加载器加载
ClassLoader中loadClass方法的源码:
如果parent!=NULL 可以委派上级loadClass;
如果没有上级(ExtClassLoader 扩展类加载器),则parent==null 委派BootstrapClassLoader
如过每一层到找不到
重写findClass方法 无法被父类加载器加载的类最终会通过这个方法被加载。
使用双亲委派模型的好处
- 保证java稳定运行,避免类重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类)
- 如果不用双亲委派模型,每个类加载器自己加载自己,可能导致类重复加载,比如java.lang.Object 可能会被加载为多个不同的类