上篇文章说了java类加载源码,双亲委派的加载。
一、自定义类加载器
1、全盘负责委托机制
“全盘委托”指当一个classLoader装载一个类时,除非显示的使用另外一个classLoader加载,否则该类所依赖的类也由该classLoader加载。
2、自定义类加载器
自定义继承的classLoader默认是app类加载器,上面还有ext扩展类加载器,以及bootStrapClass核心类加载器。
首先需要继承ClassLoader
因为这个类有两个关键方法,loadClass(String,boolean)实现了双亲委派,另一个findClass,默认是空方法,需要自己重写findClass。
findClass里我们重写的一个方法是defineClass也是jvm自己的一个方法逻辑。
这时候我们的sout里面打印的是什么类的加载器呢?
答案是app加载器,为什么,原因就是双亲委派,因为我们前面已经有一个MAIN230629这个类,它是由app类加载器加载。
如果我们把项目里这个类删掉,那么它打印的就是我们自定义你的myClassLoadTest。
3、打破双亲委派
我们前面自定义的loadClass是调用父类的,父类里面是支持双亲委派的,那么我们自己如何打破呢?
重写父类的loadClass,和findClass一样进行重写。
把双亲委派那段注释。
流程则是先看自己是否有,没有为null的时候,直接调用findClass自己去加载。
需要注意:核心类都不能加载
Object.class会报沙箱机制安全问题,因为不能加载。
所以不光要解决双亲委派加载问题,还要解决核心类由引导加载器加载,而自己定义的类由自定义加载器加载。
所以我在代码里加了如果不是我自己定义的包开头,则去用parent加载。
因为现在打破了双亲委派,再执行main方法。
结果输出的是:myClassLoader