java类加载的理解

171 阅读2分钟

java类加载器涉及三个类:bootstrapclassloader;extclassloader;appclassloader。

java类加载的双亲委派机制:我们的一个文件需要加载appclassloader会从自己的缓存中查看是否加载过该类,如果加载过那么直接返回;如果没有加载过,则会向上委托给它的父加载器extclassloader,extclassloader会从自己的缓存中查看是否加载过该类,如果加载过直接返回,如果没有加载过则会继续向上委托它的父加载器bootstrapclassloader;bootstrapclassloader会从自己的缓存中查看是否加载过该类,如果加载过,直接返回;如果没有加载过,那么它会查看自己的加载路径下是否包含该类,如果包含该类,那么它会加载该类,并将结果返回;如果不包含该类,那么它会向下投递给自己的子加载器extclassloader,extclassloader会从自己的加载目录查看是否包含该类,如果包含,则它会加载该类,并将结果返回;如果不包含,那么它会继续往下投递,交给自己的子加载器appclassloader,最终这个任务又回到了应用级别的appclassloader,将由appclassloader负责加载该类。

从类加载的这个流程中我们可以看出,1.每个类加载器都会有自己的缓存,加载过的类会缓存起来,避免了重复加载,达到复用效果,提高加载效率;2.这种做法加强了安全性,使我们不能通过自定义系统类蒙骗jvm。

类加载的三个classloader,虽然存在父加载器、子加载器的关系但是他们并不存在继承关系。 classloader是一个抽象类,定义了类加载的基本方法:secureclassloader继承了classloader,拓展了classloader类,加入了一些权限方面的功能,加强了安全性;urlclassloader继承secureclassloader,实现了通过url路径来加载类和资源;extclassloader和appclassloader都继承子urlclassloader,他们负责加载的路径不同。

bootstrapclassloader不继承classloader,它是一个用C/C++写的类,java层引用不到,所以当我们用extclassloader.getparent()方法时返回的是null,但他们直接确实存在父加载器和子加载器的关系。bootstrapclassloader负责加载jvm虚拟机运行时所需要的类,并且jvm的启动就是由它创建一个初始类来完成的。

要自己实现一个类加载器只需要1.继承抽象类classloader,2.复写findclass()方法,并在该方法中调用defineclass()。