谈谈类加载器!关于类加载器的源码

一、类加载
1.1、在java代码中,类型的加载,连接,初始化过程都是在程序运行期间完成的。

图示:

1.2、类型的加载——这里的类型是指的什么?

答:类型就是指的我们Java源代码通过编译后的class文件。
1.3、类型的来源有哪些?

(1)本地磁盘

(2)网络下载,class文件

(3)war,jar下加载,class文件

(4)从专门的数据库中读取,class文件(少见)

(5)将java源文件动态编译成class文件

1)典型的就是动态代理,通过运行期生成class文件

2)我们的jsp会被转换成servlet,而我们的serlvet是一个java文件,会被编译成class文件
1.4、通过什么来进行加载?(类加载器)

1.5、类加载的分类以及各种加载职责以及层级结构

(1)系统级别

1)启动类加载器

2)扩展类加载器

3)系统类加载器(App类加载器)

(2)用户级别的

自定义类加载器(继承我们的ClassLoader)

(3)层级结构

二、类加载器加载我们的Class的时候遵循我们的双亲委派模型

在双亲委派机制中,各个加载器按照父子关系形成树型结构,除了根加载器以外,每一个加载器有且只有一个父加载器

1、源码分析:
复制代码

1 protected Class<?> loadClass(String name, boolean resolve)
2 throws ClassNotFoundException
3 {
4 synchronized (getClassLoadingLock(name)) {
5 //检查当前的class对象是否被加载过,被加载过就返回
6 Class<?> c = findLoadedClass(name);
7 if (c == null) {
8 long t0 = System.nanoTime();
9 try {
10 //判断当前的classLoader是否有父类
11 //若存在父类
12 if (parent != null) {
13 //调用父类的loadClass
14 c = parent.loadClass(name, false);
15 } else {//不存在父类,表示当前的classLoader是extClassLoader
16 //那么就会调用启动类判断是否加载过
17 c = findBootstrapClassOrNull(name);
18 }
19 } catch (ClassNotFoundException e) {
20 // ClassNotFoundException thrown if class not found
21 // from the non‐null parent class loader
22 }
23 //到目标位置,app ext boot都没有去加载过
24 if (c == null) {
25 // If still not found, then invoke findClass in order
26 // to find the class.
27 long t1 = System.nanoTime();
28 //委托我们的子类的classLoader去找
29 c = findClass(name);
30
31 // this is the defining class loader; record the stats
32 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 ‐ t0);
33 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
34 sun.misc.PerfCounter.getFindClasses().increment();
35 }
36 }
37 if (resolve) {
38 resolveClass©;
39 }
40 return c;
41 }
42 }

复制代码
2、双亲委派模型加载的流程图

3、类加载器的双亲委派模型的好处:

总所周知:java.lang.object类是所有类的父类,所以我们程序在运行期间会把java.lang.object类加载到内存中,假如java.lang.object类能够被我们自定义类加载器去加载的话,那么jvm中就会存在多份Object的Class对象,而且这些Class对象是不兼容的。

所以双亲委派模型可以保证java核心类库下的类型的安全。

借助双亲委派模型,我们java核心类库的类必须是由我们的启动类加载器加载的,这样可以确保我们核心类库只会在jvm中存在一份这就不会给自定义类加载器去加载我们核心类库的类。

根据我们的演示案例,一个class可以由多个类加载器去加载,同事可以在jvm内存中存在多个不同版本的Class对象,这些对象是不兼容的。
4、如何手写一个自定义类加载器(根据ClassLoader的doc文档)

(1)我们自定义类加载器必须要继承ClassLoader

(2)我们必须要findClass(String name)方法
复制代码

1 /**
2 * Finds the class with the specified binary name.
3 * This method should be overridden by class

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值