1、启动类加载器:负责加载 Java_HOME/lib 目录中的类库
2、扩展类加载器:负责加载 Java_HOME/lib/ext 目录中的类库
3、应用程序类加载器:负责加载用户路径(classpath)上的类库
既然有这么多加载器,加载一个类时使用的是哪个类加载器?
如果不同类加载器有同名类,以哪个为准,如何避免类名冲突?
双亲委派机制就是为了解决这个问题。
双亲委派机制是指一个类在收到类加载请求后不会尝试自己加载这个类,而是把该类加载请求向上委派给其父类加载器去完成,其父类加载器在接收到该类加载请求后又会将其委派给自己的父类,以此类推,这样所有的类加载请求都被向上委派到启动类加载器中。若父类加载器在接收到类加载请求后发现自己也无法加载该类(通常原因是该类的Class文件在父类的类加载路径中不存在),则父类会将该信息反馈给子类并向下委派子类加载器加载该类,直到该类被成功加载,若找不到该类,则JVM会抛出ClassNotFoud异常。
将自定义加载器挂载到应用程序类加载器。
- 应用程序类加载器将类加载请求委托给扩展类加载器。
- 扩展类加载器将类加载请求委托给启动类加载器。
- 启动类加载器在加载路径下查找并加载Class文件,如果未找到目标Class文件,则交由扩展类加载器加载。
- 扩展类加载器在加载路径下查找并加载Class文件,如果未找到目标Class文件,则交由应用程序类加载器加载。
- 应用程序类加载器在加载路径下查找并加载Class文件,如果未找到目标Class文件,则交由自定义加载器加载。
- 在自定义加载器下查找并加载用户指定目录下的Class文件,如果在自定义加载路径下未找到目标Class文件,则抛出ClassNotFoud异常。
通过以上流程,双亲委派机制保障了类的唯一性