java classloader详解
参考资料:
先说一下class文件里面import和package的作用。package用于对一个class进行命名。包名加上类名就是构成了类的完整限定名称。import主要是一个java语法糖,可以避免在引用每个类的时候都需要写完整限定名,在import了相应的类之后就不用再写类的完整限定名称了。在编译完成后的class文件里面都是采用的完整限定名称。
1. java程序包是由多个class文件构成的,在java程序启动的时候,jvm会使用classloader去从指定的位置中寻找class文件,并且将class文件的内容读入内存中创建class对象。classloader就是用来加载class对象的。
2. java默认提供了三个classloader,第一个是bootstrapclassloader,这是native(c++)实现的,属于jvm的一部分,没有继承classloader这个抽象类,bootstrapclassloader主要负责加载jdk中的核心类库,可以通过System.out.println(System.getProperty("sun.boot.class.path"))打印出来看看。第二个是extension classloader,扩展类加载器,负责加载java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目录下的jar。第三个appclassloader,称之为系统类加载器,负责加载classpath所指定的目录下的所有jar。
3. 在java中,多个classloader采用一定的层次组织在一起,在加载的时候使用的是委托机制,每一个classloader都有一个父classloader,如果不显示指定一个父亲的话,那么将父亲设置为系统类加载器。当需要加载一个class的时候,如果一个class已经被加载了那么直接返回,否则委托给父classloader去加载,如果父classloader没有load的话那么就依据指定路径去findclass。图和相应代码如下:
代码应该更直观一点![](https://images2015.cnblogs.com/blog/411850/201601/411850-20160105190321809-934955936.png)
![](https://images2015.cnblogs.com/blog/411850/201601/411850-20160105190321809-934955936.png)
![](https://images2015.cnblogs.com/blog/411850/201601/411850-20160105190338996-242577776.png)
![](https://images2015.cnblogs.com/blog/411850/201601/411850-20160105190404825-174913386.png)
4. 使用3这种加载的好处是可以避免重复加载,从安全方面讲这样可以避免我们用自定义的类型去覆盖了java核心api中的类。