深入理解Java类加载机制,以及破坏双亲委派模型的实现方式

关于类加载器

类加载器的使用

//隐式加载
User user=new User();
//显式加载,并初始化
Class clazz=Class.forName("com.test.java.User");
//显式加载,但不初始化
ClassLoader.getSystemClassLoader().loadClass("com.test.java.Parent

了解类加载器的必要性

开发人员大多数时候并不需要显示地使用类加载器,但了解整个机制对于了解类本身却很有用。

  • 遇到java.lang.ClassNotFoundException异常或java.lang.NoClassDefFoundError异常的时候,能够读懂日志
  • 通过类加载器进行字节码加解密,或实现更多的功能

命名空间

对于任意一个类都需要由它的类加载器和这个类本身一同确认其再Java虚拟机的唯一性,具体而言,底层通过native方法findLoadedClass0来完成该操作。意味着每一给类加载器都有自己的独特的命名空间。

沙箱安全机制

Java设计了沙箱安全机制,用于将部分Java代码限定在JVM特定的范围内,严格限制其对系统底层资源的使用,例如CPU,内存,文件系统等。
早期,沙箱是独立的,例如加载远程代码的时候,沙箱负责确保这些代码的隔离。
请添加图片描述

后来,沙箱机制被进一步完善。具体而言,引入了域、权限组、签名等协议,统一地在系统域进行交互。它很像操作系统的用户态和和核心态的关系。
请添加图片描述

类加载器的关系

三层结构

从类加载器的三层结构来看,它们之间的关系如下图,在底层的实现中,每一层的类加载器都包含父加载器parent的引用。各个加载器加载的内容不相同,可以使用-XX:+TraceClassLoading答应。
请添加图片描述

  • 启动类(引导类)加载器,负责加载核心库,它用C++实现,所以也没有对应的Java对象——因而子类的parent引用固定为null。
  • 拓展类加载器,从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext子目录下加载类库
  • 应用类(系统类)加载器,负责加载各种应用程序类
  • 用户自定义类加载器,父加载器默认是应用类加载器
代码继承关系

![image.png](https://img-blog.csdnimg.cn/img_convert/16a64b49811f59931301ab79da00ab4c.png#clientId=u5925fd29-86df-4&from=paste&height=449&id=uaa91e2de&margin=[object Object]&name=image.png&originHeight=449&originWidth=565&originalType=binary&ratio=1&size=258886&status=done&style=none&taskId=ub3a65416-1609-43e5-bde3-760c75e08c9&width=565)

从源码角度理解双亲委派机制

双亲委派模型是Java类加载中遵循的加载模型——按照三层结构,一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就成功返回。只有父类加载器无法完成此加载任务时,才自己去加载。

源码理解

请添加图片描述

从代码继承关系来看,ClassLoader提供了一个共有的类加载器的抽象模板。该类的实现也非常简单,核心代码只有一个——loacClass

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
   
	synchronized (getClassLoadingLock(name)) {
   
		// 查看该类是否被当前加载器加载
		Class<?> c = findLoadedClass(name);
		if (c == null) {
   
			long t0 = System.nanoTime();
			try {
   
				// 如果父加载器存在,则调用父加载器的方法
				if (parent != null) {
   
					c = parent.loadClass(name, false);
				} else {
   
					// 父加载器 == null,说明是引导类加载器,查看引导类加载器是否加载
					c = findBootstrapClassOrNull(name);
				}
			} catch (ClassNotFoundException e) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值