20_类加载器命名空间实战剖析与透彻理解
类加载器命名空间实战剖析与透彻理解
代码:
package top.tomxwd.classloader;
public class MyTest17_1 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
MyTest16 loader1 = new MyTest16("loader1");
loader1.setPath("C:\\Users\\weidou.xie\\Desktop\\");
Class<?> clazz = loader1.loadClass("top.tomxwd.classloader.MySample");
System.out.println("clazz.hashCode() = " + clazz.hashCode());
// 如果注释下面这行,那么不会实例化MySample对象,即MySample构造方法不会被调用
// 因此不会实例MyCat对象,即没有对MyCat进行主动使用,这里就不会加载MyCat Class
Object obj = clazz.newInstance();
}
}
测试1:
不做删除,保持原样,发现是应用类加载器进行加载两个类。
测试2:
删掉项目编译出来的MySample.class以及MyCat.class,然后运行,发现使用到MyTest16自定义加载器进行加载了(且是同一个类加载器进行加载)。
测试3:
删掉项目中的MyCat.class文件,保留MySample.class,运行,发现报错,原因其实可以根据测试2推出,因为MyCat是在MySample构造方法里实例化的,所以MyCat是由加载了MySample的类加载器尝试加载的,而加载MySample的加载器是应用类加载器,而我们删了类路径下的MyCat.class文件,因此是不能加载到MyCat的(双亲委托机制委托到扩展类加载器,再到系统类加载器,最后再返回到应用类加载器,应用类加载器无法加载,因此报错)。
测试4:
删掉项目中的MySample.class文件,保留MyCat.class,运行,不会报错,而且结果是MyTest16自定义类加载器对MySample进行加载,而MyCat是由应用类加载器进行加载的,原因也是因为双亲委托机制。
评论区