Java类加载器(双亲委派模型)

目录

1、类与类加载器

2、双亲委派模型

2.1、双亲委派模型的工作过程是:

2.2、破坏双亲委派模型


类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到 Java 虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为类加载器

1、类与类加载器

类加载器虽然只用于实现类的加载动作,但它在 Java 程序中的作用却远超类加载阶段。对于任意一个类,都必须由加载它的类加载器和这个类本身一同确立其在 Java 虚拟机中的唯 一性,每一个类加载器,都拥有一个独立的类名称空间。换句话说,比较两个类是否相等, 只有在这两个类是由同一个类加载器(实例)加载的前提下才有意义,否则,即使这两个来源于同一个 Class 文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那这两个类必定不相等。

这里所指的相等,包括类的 Class 对象的 equals 方法等的返回结果,也包括 instance of 的 返回结果。

2、双亲委派模型

从 Java 虚拟机角度来讲,只存在两种不同的类加载器:

  • 一种是启动类加载器(bootstrap classloader),这个类加载器由 C++语言实现(HotSpot),是虚拟机自身的一部分;
  • 另一 种就是所有的其他类加载器,都由 Java 语言实现,独立于虚拟机外部。并且全继承自 java.lang.ClassLoader。

从 Java 开发人员的角度看,Java 程序使用到以下 3 种系统提供的类加载器:

  • 启动类加载器(Bootstrap Class Loader):负责将存放在<JAVA_HOME>\lib 目录中的类库加载到虚拟机内存中。启动类加载器无法被 Java 程序直接引用;
  • 扩展类加载器(Extension ClassLoader):这个类加载器负责加载<JAVA_HOME>\lib\ext 目录中的所有类库, 开发者可以直接使用扩展类加载器来加载Class文件;
  • 应用程序类加载器(Application ClassLoader):或称系统类加载器,负责加载用户路径 classpath 下所有指定的类库,开发者可以直接使用这个类加载器,如果应用程序中没有自定 义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

类加载器之间的层次关系称为类加载器的双亲委派模型(Parents Delegation Model)。双亲委派模型要求除了顶层了启动类加载器,其他的类加载器都应当有自己的父类加载器。这里类加载器之间的父子关系一般不会以继承的关系来实现,而是使用组合的方式来复用父加载器的代码。

2.1、双亲委派模型的工作过程是:

 如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此, 因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求,子加载器才会尝试自己去加载。

使用双亲委派模型来组织类加载器之间的关系,有一个显而易见的好处就是 Java 类随它的类加载器一起具备了一种带有优先级的层次关系。如果没有使用双亲委派模型,都由各个类加载器自行去加载的话,如果用户自己也编写一个名为java.lang.Object的类,并放在程序的ClassPath中,那系统中就会出现多个不同的Object类,Java类型体系中最基础的行为也就无法保证,应用程序将会变得一片混乱。

2.2、破坏双亲委派模型

双亲委派模型并不是一个强制性的约束模型,而是 Java 设计者推荐给开发者的类加载器实现方式。比如 OSGi 环境下,类加载不再是双亲委派模型中的树形结构,而是进一步发展为更加复杂的网状结构,当收到类加载请求,OSGi 将按照下面的顺序进行类搜索:

  1. 将以java.*开头的类,委派给父类的加载器加载;
  2. 否则,将委派列表名单内的类,委派给父类加载器加载;
  3. 否则,将Import列表中的类,委派给Export这个类的Bundle的类加载器加载;
  4. 否则,查找当前Bundle的ClassPath,使用自己的类加载器加载;
  5. 否则,查找类是否在自己的Fragment Bundle中,如果在,则委派给Fragment Bundle的类加载器加载;
  6. 否则,查找Dynamic Import列表的Bundle,委派给对应Bundle的类加载器加载;
  7. 否则,类查找失败。

2.3、热部署

如果我们希望将 java 类卸载,并且替换更新版本的 java 类,该怎么做呢?

  1. 销毁该自定义 ClassLoader;
  2. 更新 class 文件;
  3. 创建新的 ClassLoader 去加载更新后的 class。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值