博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
不同的类加载器加载的类不是同一个类
阅读量:2489 次
发布时间:2019-05-11

本文共 1586 字,大约阅读时间需要 5 分钟。

一、定义类加载器、初始类加载器

类加载器结构:

  • bootstrap
    • ExtClassloader
      • AppClassloader
        • 自定义clsloadr1
        • 自定义clsloadr2

如果用“自定义clsloadr1”加载java.lang.String类,那么根据双亲委派最终bootstrap会加载此类,那么bootstrap类就叫做该类的“定义类加载器”,而包括bootstrap所有得到该类class实例类加载器都叫做“初始类加载器”。

二、命名空间

命名空间是指jvm为每个类加载器维护的一个“表”,这个表记录了所有以 此类加载器 为 “初始类加载器”(而不是定义类加载器,所以一个类可以存在于很多的命名空间中)加载的类的列表。

例如:

CLTest是AppClassloader加载的String通过加载CLTest的类加载器,也就是AppClassloader进行加载,但最终委派到bootstrap加载的(当然,String类其实早已经被加载过了,这里只是举个例子)。所以,对于String类来说,bootstrap是“定义类加载器”,AppClassloader是“初始类加载器”。根据刚才所说,String类AppClassloader命名空间中(同时也在bootstrapExtClassloader的命名空间中,因为bootstrap,ExtClassloader也是String的初始类加载器),所以CLTest可以随便访问String类。这样就可以解释“处在不同命名空间的类,不能直接互相访问”这句话了。

三、

一个类由不同的类加载器实例加载的话,会在方法区产生两个不同的类彼此不可见,并且在中生成不同Class实例

四、

那么由不同类加载器实例(比如-自定义clsloadr1,-自定义clsloadr2)所加载的classpath下和ext下的类,也就是由我们自定义的类加载器委派给AppClassloader和ExtClassloader加载的类,在内存中是同一个类吗?

所有继承ClassLoader并且没有重写getSystemClassLoader方法的类加载器,通过getSystemClassLoader方法得到的AppClassloader都是同一个AppClassloader实例,类似单例模式。

在ClassLoader类中getSystemClassLoader方法调用私有的initSystemClassLoader方法获得AppClassloader实例,在initSystemClassLoader中:

sun.misc.Launcher l = sun.misc.Launcher.getLauncher();...scl = l.getClassLoader();

AppClassloader是sun.misc.Launcher类的内部类,Launcher类在new自己的时候生成AppClassloader实例并且放在自己的私有变量loader里:

loader = AppClassLoader.getAppClassLoader(extclassloader);

值得一提的是sun.misc.Launcher类使用了一种类似单例模式的方法,即既提供了单例模式的接口getLauncher(),又把构造函数设成了public的。但是在ClassLoader中是通过单件模式取得的Launcher 实例的,所以我们写的每个类加载器得到的AppClassloader都是同一个AppClassloader类实例

这样的话得到一个结论,就是所有通过正常双亲委派模式的类加载器加载的classpath下的和ext下的所有类在 方法区 都是 同一个类,堆中 的 Class实例 也是同一个

转载地址:http://nwdrb.baihongyu.com/

你可能感兴趣的文章
suse创建的虚拟机,修改ip地址
查看>>
linux的挂载的问题,重启后就挂载就没有了
查看>>
docker原始镜像启动容器并创建Apache服务器实现反向代理
查看>>
docker容器秒死的解决办法
查看>>
管理网&业务网的一些笔记
查看>>
openstack报错解决一
查看>>
openstack报错解决二
查看>>
linux source命令
查看>>
openstack报错解决三
查看>>
乙未年年终总结
查看>>
子网掩码
查看>>
第一天上班没精神
查看>>
启动eclipse报错:Failed to load the JNI shared library
查看>>
eclipse安装插件的两种方式在线和离线
查看>>
linux下源的相关笔记(suse)
查看>>
linux系统分区文件系统划分札记
查看>>
Linux(SUSE 12)安装Tomcat
查看>>
Linux(SUSE 12)安装jboss4并实现远程访问
查看>>
Neutron在给虚拟机分配网络时,底层是如何实现的?
查看>>
netfilter/iptables全攻略
查看>>