vs 未能加载此自定义查看器_Java 中的「类加载机制」是怎样的呢?

12a895311accef8525eb4c5441173796.png

我们都知道 Java 程序的运行是以 JVM 为基础的,JVM 即 Java 虚拟机。

而 JVM 会默认提供三个主要的类加载器:

  • BootStrap:引导类加载器
  • ExtClassLoader:扩展类加载器
  • AppClassLoader:系统类加载器

分别详细介绍下:

BootStrap 是用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader;

ExtClassLoader 加载 JVM 提供的扩展库目录下的 Java 类;

AppClassLoader 是根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。


除了 BootStrap 外,每个类加载器都有一个「父'类加载器」,通过类加载器调用 getParent() 方法能够得到他的「父'类加载器」。


现实项目中,我们可能会编写自己的类去继承「java.lang.ClassLoader」来实现我们自己的类加载器,从而达到某种目的。一般我们创建的类加载器的「父'类加载器」是 AppClassLoader。

而 AppClassLoader 的「父'类加载器」是ExtClassLoader;

ExtClassLoader 的「父'类加载器」则是 BootStrap。

所以我们使用类加载器的结构用一张「树形图」可以很直白的表现出来。

eabbbbfeb4d0b37e3856779dff5911b0.png

为了校验,写了一个简单的例子来验证一下:

51e859ab5fdeb13355c5128d29066007.png

得到的结果是

62a511cfbd6663d4d6cae1b6bed213a4.png

我们自定义的类加载器的父类加载器是 AppClassLoader;

而 AppClassLoader 的父类加载器是 ExtClassLoader;

ExtClassLoader 的父类加载器打印是 null,原因是他并不是 java 类。

好了,类加载器的层级结构我们明白之后,我们再来看下类加载器的委托机制

双亲委托

我们先来看个例子吧,这个例子由 eclipse 编写

例1:

e7ba5e458e886164d76cb2e2e784a60b.png

打印的结果是

246db64943667cb8a0b308db56642d12.png

说明了加载我们当前类的类加载器是 AppClassLoader

而 System 是属于系统提供jar类:rt.jar 中的类,所以是由 BootStrap 加载的,所以返回结果为 null。

不过这个例子并不能观察出 “类加载器的委托机制”。我们需要将此项目打包成 jar 文件,然后再放到 ext/目录 下,然后再来运行看看:

例2:

5b47db31e239338494bc6530c440264c.png
c30f8c0c7c98f1f2d853b2cd0c3568e3.png

这个时候发现打印结果是不是变成了 ExtClassLoader。

对比一下我们在 eclipse 运行的代码 打印结果是 AppClassLoader,是不是看出点什么端倪?

其实这只是类加载器的委托机制的表象,我们还是看一下它的加载机制是什么吧。


我们自定义的类会向 AppClassLoader 发送加载请求

AppClassLoader 会向 ExtClassLoader 发送加载请求

ExtClassLoader 则会向 BootStrap 发送加载请求

此时 BootStrap 由于没有父类加载器,所以他会尝试加载我们自定义的类,但是由于BootStrap 的职责是加载 Java 的核心库,而在核心库中并未找到自定义类,所以无法加载。

此时会将加载权给 ExtClassLoader,ExtClassLoader 的职责是加载 lib/ext 库中的库,而我们第一个例子中没有将 jar 包放到 ext 目录下,所以第一个例子中 ExtClassLoader 没有加载到。

而第二个例子中,我们把 jar 包放到了 ext 下,所以 ExtClassLoader 加载到了。


继续第一个例子,ExtClassLoader 没有加载到自定义类,所以把加载权给了 AppClassLoader,而 AppClassLoader 就是为加载这种自定义类而存在的,自然也就加载了。

整理成流程图则是这样的

3be9f4de838d9fc65e9204edd9735447.png

下篇网站我会创建一个自定义的类加载器,然后分析一下 ClassLoader 类的加载流程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值