1、双亲委托模型
从java虚拟机角度讲,只存在两种类加载器
1、启动类加载器 BootstrapClassLoader,是C++语言实现
2、其他类加载器,java实现
从开发人员角度讲,划分三类
1、启动类加载器(BootstrapClassLoader)
负责加载JAVA_HOME/lib目录下或被-Xbootclasspath指定路径
2、扩展类加载器(ExtensionClassLoader)
负责加载<JAVA_HOME>\lib\ext
3、应用类加载器(ApplicationClassLoader)
负责加载用户类路径上的指定类库
类加载器之间父子关系是以组合关系来复用父加载器代码
双亲委托工作流程:
如果一个类加载器收到类加载请求,他首先不会自己尝试加载这个类,而是将这个请求委派给父类加载器完成,每一个层次加载器都是如此,直到委托到启动类加载器,只有父类反馈无法完成请求,子类才尝试加载
2、为什么使用双亲委托
1、因为可以避免重复加载,当父类已经加载该类,就没有必要让子类再加载一次。
2、考虑安全因素,如果用自定义同名类来动态替换java核心api中定义类型,存在非常大隐患,除非自定义ClassLoader搜索算法
3、JVM在搜索类中,如何判定两个class相同
1、判断两个类名是否相同
2、是否由同一个类加载器实例加载
4、代码实现
protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
//首先检查类是否加载过
Class<?> clazz = findLoadedClass(className);
if (clazz == null) {
try {
//如果存在父节点,加载父加载器ClassLoader
if(parent!=null){
//如果没有加载过,先调用父加载器的loadClass
clazz = parent.loadClass(className, false);
}else{//否则用启动类加载器
clazz= findBootstrapClassOrNull(className);
}
} catch (ClassNotFoundException e) {
//抛出异常说明父类无法完成加载请求
if(clazz == null){
clazz = findClass(className);
}
}
}
//解析class
if(resolve){
resolveClass(clazz)
}
return clazz;
}
网友评论