打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
通过自定义类加载器来验证双亲委托机制

上一篇文章我们知道了类加载器通过组合方式实现了双亲委托,那么类又是如何具体加载的呢?

类加载过程

         回顾下类加载的源码,如下图:

         上一篇文章中自定义的类加载器直接重写了loadClass,打乱了类加载的双亲委托机制,今天需要在不破坏这个机制下自定义!

         从源码中可以看出如果在parent最终不能加载的情况下,会来到第3步由当前加载器来加载,而第3步最关键的代码就是“ c = findClass(name)”。我们先找到应用类加载器Launcher.AppClassLoader并没有findClass(name)方法,不过它的父类URLClassLoader实现了findClass方法,方法代码如下图:

        

         可以看到这个方法在获取要加载类的正真文件,继续跟definClass方法最后会调用ClassLoader.defineClass,在这个方法里面会调用一个defineClass1的本地方法!

自定义类加载器

         从以上分析出我们如果想自定义一个类加载器,同时不破坏双亲委托机制,最关键的是重写findClass方法,所以我们就可以自定义实现类加载器了,代码如下图:

        

         自定义的classLoader给他新增了一个名称属性,并且重写了findClass,同时在findClass方法第一行打印了类加载名称和加载的类名称。

         写一个测试方法并运行,运行结果如下图:

        

         根据打印结果可以判断并没有运行findClass方法,这是什么原因呢?

         在自定义的类加载器中构造函数没有显示的执行super()就会默认执行父类的默认构造函数,也就是ClassLoader的默认构造函数,它设置的parent是AppClassLoader

         而我们加载的类“com.dggcc.test.classload.ClassLoadTest”在当前工程下,是可以被AppClassLoader所加载的,所以最终并不会执行MyClassLoader的findClass方法

         对类加载器进行改造,使他去加载指定文件夹下的文件,改造后代码如下图:

        

         在加载器中添加一个属性path,同时查找class文件的时候只在这个文件下加载,测试代码如下图:

        

         首先要把ClassLoadTest.class移到你想加载的路径下,然后要把把项目下对应的ClassLoadTest.class文件删除,否则在加载的时候AppClassLoader还是能找到“com.dggcc.test.classload.ClassLoadTest”对应的class文件,能够加载成功。删除后由于系统自带的加载器都不能加载这个类,最终由我们自定义的类加载加载,从打印结果可以验证我们的结论!

测试验证结论

         通过自定义类加载我们就可以很方便的验证之前的一些结论,测试代码如下图:

        

         可以看到myclassLoad1对同一个类加载2次,但是真正只加载了一次,并且根据类的hashCode也可以看出来是同一个class对象。而如果再次new一个myclassLoad2出来对同一个class文件加载,就再次加载了一次,并且hashCode也不同不是同一个class对象!

         可以得出结论:同一个类只会被同一个类加载器加载一次,不同的类加载器加载同一个class文件加载出来的class对象也不相同!

         我们对代码再次改造进行测试,改造代码如下图:

        

         新建了一个构造函数用来设置parent属性,通过结果可以看到类只被加载了一次,这是因为myclassLoad1作为了myclassLoad2的parent。所以myclassLoad2在加载类的时候会去myclassLoad1找是否加载。如果加载了myclassLoad2就不会再加载了!

         如果在myclassLoad2之前不加载类,测试代码如下图:

        

         可以看到正真加载类的还是myclassLoad1,也就是双亲委托机制!

总结

         结合上一篇我们知道重写loadClass方法可能会破坏双亲委托机制,而只重写findClass则不会,同时可以实现去加载其他地方的class文件。

         通过自定义类加载我们再次验证了类的加载机制,同一个类只会被同一个类加载器加载一次,不同的类加载器加载同一个class文件加载出来的class对象也不相同! 并且再次验证了双亲委托加载类。

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
类加载机制(类加载过程和类加载器)
Java虚拟机类加载器及双亲委派机制
JVM真香系列:轻松理解class文件到虚拟机(下)
深入理解JVM类加载器
Java虚拟机学习(10):类加载器(ClassLoader)
ClassLoader的原理及应用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服