概述
我们知道JVM加载类的过程遵循“双亲委派机制”,每当JVM启动时,是通过一个ClassLoader来加载class文件的。
ClassLoader有三个实现,分别是:BootstrapLoader,ExtClassLoader和AppClassLoader.
三个类加载器的作用不同,所加载的class文件也不相同。
下面我们通过代码实现查看三个类加载器分别所加载的class路径
/**
*
* @author JJ_knows
*
*/
public class ClassLoaderTest {
public static void main(String[] args) {
System.out.println("启动类加载器加载的类:");
String bootPath = System.getProperty("sun.boot.class.path");//启动类加载器所加载的是JVM中最底层的类,加载时的搜索路径是sun.boot.class.path。
System.out.println(bootPath.replaceAll(";",System.lineSeparator()));
System.out.println("......................");
System.out.println("扩展类加载器加载的类:");
String extPath = System.getProperty("java.ext.dirs");//扩展类加载器是用来加载java的一些库的,加载时的搜索路径是java.ext.dirs
System.out.println(extPath.replaceAll(";",System.lineSeparator()));
System.out.println("......................");
System.out.println("应用类加载器加载的类:");
String appPath = System.getProperty("java.class.path");//应用类加载器搜索路径是java.class.path
System.out.println(appPath.replaceAll(";",System.lineSeparator()));
}
}
输出结果:
启动类加载器加载的类:
D:jdk8Javajdk1.8.0_162jrelibresources.jar
D:jdk8Javajdk1.8.0_162jrelibrt.jar
D:jdk8Javajdk1.8.0_162jrelibsunrsasign.jar
D:jdk8Javajdk1.8.0_162jrelibjsse.jar
D:jdk8Javajdk1.8.0_162jrelibjce.jar
D:jdk8Javajdk1.8.0_162jrelibcharsets.jar
D:jdk8Javajdk1.8.0_162jrelibjfr.jar
D:jdk8Javajdk1.8.0_162jreclasses
......................
扩展类加载器加载的类:
D:jdk8Javajdk1.8.0_162jrelibext
C:WindowsSunJavalibext
......................
应用类加载器加载的类:
D:jdk8Javajdk1.8.0_162jrelibresources.jar
D:jdk8Javajdk1.8.0_162jrelibrt.jar
D:personalreadTemplateDemolbgw-webtargettest-classes
D:personalreadTemplateDemolbgw-webtargetclasses
D:repositoryorgapachelogginglog4jlog4j-api2.7log4j-api-2.7.jar
D:repositoryorgapachelogginglog4jlog4j-core2.7log4j-core-2.7.jar
D:ideaIU-2017.2.winlibidea_rt.jar
双亲委派机制的加载过程是如何实现的呢?
ClassLoader中有一个 loadClass()方法,我们进入这个方法查看:
我们可以看到加载类时,首先通过:应用类加载器->扩展类加载器->启动类加载器的顺序 ,从下到上的依次进行检查,看是否已经被加载。如果已经被加载,则直接返回。
如果并未被加载过:
ExtClassLoader 和AppClassLoader 等类加载器,通过重写这个findClass()方法,实现对不同路径下的类进行加载。
由此可知,当我们自定义类加载器的时候,只需继承ClassLoader并重写这个方法即可。
(注意这里采用的设计模式: 模板方法。)
为何要采用双亲委派机制,它的作用是什么呢?
1. 避免了重复加载
2.出于安全考虑,保证了java核心类不被篡改。
那可不可以打破“双亲委派机制”?如何打破?
很简单,只需要重写loadClass()方法就可以了。
最后
以上就是无辜绿茶为你收集整理的类加载的过程中,不同类加载器的加载路径测试的全部内容,希望文章能够帮你解决类加载的过程中,不同类加载器的加载路径测试所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复