类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、应用程序(application)也叫【系统加载器(System)】和用户自定义类加载器(java.lang.ClassLoader的子类)。
双亲委派机制:JVM在加载类时默认采用的是双亲委派机制。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
1.当Application ClassLoader 收到一个类加载请求时,他首先不会自己去尝试加载这个类,而是将这个请求委派给父类加载器Extension ClassLoader去完成。
2.当Extension ClassLoader收到一个类加载请求时,他首先也不会自己去尝试加载这个类,而是将请求委派给父类加载器Bootstrap
ClassLoader去完成。
3.如果Bootstrap ClassLoader加载失败(在
4.如果Extension ClassLoader也加载失败,就会使用Application ClassLoader加载。
5.如果Application ClassLoader也加载失败,就会使用自定义加载器去尝试加载。
1、Bootstrap ClassLoader :启动类加载器,主要加载核心类库,也就是我们环境变量下面%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等;
2、Extention ClassLoader :扩展类加载器,加载目录%JRE_HOME%\lib\ext目录下的jar包和class文件;
3、Application ClassLoader:应用程序类加载器, 加载当前应用的classpath的所有类;
4、自定义类加载器:程序员自己定义的类加载器。
1.避免重复加载:父亲加载完成的一个类,子类直接用,不用子类的ClassLoader再次加载
2.避免核心类被篡改:Java的核心api的父亲已经加载了一个java.lang.Integer类,如果传来一个子类要加载一个篡改过的类,那么拒绝加载,因为直接用父亲的。
不是:tomcat 为了实现隔离性,没有遵守这个约定,每个webappClassLoader加载自己的目录下的class文件,不会传递给父类加载器。
https://zhuanlan.zhihu.com/p/336573124?utm_id=0 双亲委派模型讲述很详细的一篇文章
https://blog.csdn.net/u010312474/article/details/91046318
https://www.cnblogs.com/developer-ios/p/5550789.html