概要
这两天看了大量关于java类加载器的文章,有很多疑问一只困扰着我,今天折腾了半天,又通过自己写了一个自定义加载器,总算基本搞清楚了。在这里总结一下,若有错误的地方,还希望各位指正。
为什么java需要多个类加载器?
- 保证同一个类不同版本同时存在。例如tomcat中两个应用用到了同一个class,但是版本不同,此时使用不同的加载器就可以保证两个不同版本的类同时存在了;
- 可以对类进行增强。例如aop中,我们通过cglib对类A进行增强,但又不能影响其他类对A的使用。这时候我们可以使用另一个加载器来加载增强后的类A;
- 保证安全。类中的方法和属性要具有包访问权限的前提是,必须是由同一个类加载器加载的,比如lang包下的类都由bootstrap加载,但bootstrap不会加载rt.jar以外的class文件,就避免了其他文件对lang包下包访问权限的属性的更改了。
- jdk中默认的三种加载器代表了三种不同的信任级别。最可信的级别是java核心API类。然后是安装的拓展类,最后才是在类路径中的类;
加载器如何实现Class对象的隔离?
- 首先有一点要说明:所谓的不同加载器是指不同的加载器实例对象,不是指不同的加载器类。例如:AppClassLoader加载器有两个实例对象loader1和loader2,那么这两个实例对象加载的Class文件也是互相隔离;
- 可以这样理解:每个加载器的实例在方法区中都有自己的一个唯一的命名空间,它加载的所有class文件的Class对象都存放在该命名空间中。通过该命名空间就实现了不同加载器实例对同一个calss文件加载所生成的Class对象的隔离。
- 为什么父类加载器加载的类无法访问子类加载器加载的类