JVM学习笔记20——类加载器命名空间实战剖析与透彻理解

命名空间

  • 每个类加载器都有自己的命名空间,命名空间由该加载器及所有父加载器所加载的类组成
  • 在同一个命名空间中,不会出现类的完整名字(包括类的包名)相同的两个类
  • 在不同的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的两个类

还是和原来一样新建一个MyTest17_1做验证,与MyTest17不同的是,这里设置加载路径

 loader1.setPath("D:\\workspace\\");

运行的结果如下

JVM学习笔记20——类加载器命名空间实战剖析与透彻理解_第1张图片

加载MySample和MyCat的加载器还是应用类加载器,这是因为loader1的父加载器就是应用类加载器

现在我们找出MySample与MyCat复制到设置的路径下,然后从编译器里删掉,再运行一次

JVM学习笔记20——类加载器命名空间实战剖析与透彻理解_第2张图片

可以看到findClass方式被执行,这次加载MySample和MyCat的加载器是loader1本身,这是因为当前的ClassPath里已经删掉了MySample和MyCat应用类加载器找不到对应的类,只能由loader1去我们设置的路径里寻找。

重新编译之后,我们只删除MyCat.class,再运行一次

JVM学习笔记20——类加载器命名空间实战剖析与透彻理解_第3张图片

MySample正常被加载了,但是加载MyCat的时候发生了异常,这个时候是由加载Mysample的类加载器尝试去加载MyCat,因为MyCat已经从ClassPath删掉,应用类加载器无法加载。因此抛出了ClassNotFoundException

重新build之后,我们这次只删掉MySample.class,执行

JVM学习笔记20——类加载器命名空间实战剖析与透彻理解_第4张图片

loader1委托父加载器加载MySample都加载不到,由他本身去加载MySample,成功之后,MyCat是由加载了MySample的加载器loader1再去加载MyCat,这个时候再委托给父加载器,因为MyCat还在classPath里,所以应用类记载器加载成功。

在MyCat里增加一行

System.out.println("from MyCat: " + MySample.class);

重新编译之后,可以正常执行

JVM学习笔记20——类加载器命名空间实战剖析与透彻理解_第5张图片

再删掉MySample.class

JVM学习笔记20——类加载器命名空间实战剖析与透彻理解_第6张图片

出现了异常,这是因为命名空间由该加载器及所有父加载器所加载的类构成,也就是说子加载器可以看到父加载器加载的类,反过来父加载器不能看到子加载器加载的类。MySample是自定义加载器加载的,MyCat是由应用类加载器加载的,所以在MyCat中应用类加载器找不到由子加载器加载的MySample。

在MySample里增加代码,并注释掉上面MyCat新加在代码

System.out.println("from MySample: " + MyCat.class);

删掉MySample运行

JVM学习笔记20——类加载器命名空间实战剖析与透彻理解_第7张图片

结果都有正常输出,原因也在于命名空间由该加载器及所有父加载器所加载的类构成,相当于在子类加载器的命名空间中找父加载器加载的MyCat,因此不会报错。

 

微信公众号:二虎程序

JVM学习笔记20——类加载器命名空间实战剖析与透彻理解_第8张图片

源码地址:https://github.com/TigerTurbo/jvm_lecture/blob/master/src/main/java/com/yshuoo/jvm/classloader/

你可能感兴趣的:(JVM学习笔记,JVM)