JDK源码(16)-ClassLoader

简介: JDK源码(16)-ClassLoader

 

一、概述

 

image.gif编辑

这个类的作用就是根据一个指定的类的全限定名,找到对应的Class字节码文件,然后加载它转化成一个java.lang.Class类的一个实例。

二、类加载器介绍

启动类加载器(Bootstrap ClassLoader):

这个类加载器负责将\lib目录下的类库加载到虚拟机内存中,用来加载java的核心库,此类加载器并不继承于java.lang.ClassLoader,不能被java程序直接调用,代码是使用C++编写的.是虚拟机自身的一部分。

扩展类加载器(Extendsion ClassLoader):

这个类加载器负责加载\lib\ext目录下的类库,用来加载java的扩展库,开发者可以直接使用这个类加载器。

应用程序类加载器(Application ClassLoader):

这个类加载器负责加载用户类路径(CLASSPATH)下的类库,一般我们编写的java类都是由这个类加载器加载,这个类加载器是CLassLoader中的getSystemClassLoader()方法的返回值,所以也称为系统类加载器.一般情况下这就是系统默认的类加载器。

除此之外,我们还可以加入自己定义的类加载器,以满足特殊的需求,需要继承java.lang.ClassLoader类。

三、双亲委派机制

双亲委派模型是一种组织类加载器之间关系的一种规范,他的工作原理是:如果一个类加载器收到了类加载的请求,它不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,这样层层递进,最终所有的加载请求都被传到最顶层的启动类加载器中,只有当父类加载器无法完成这个加载请求(它的搜索范围内没有找到所需的类)时,才会交给子类加载器去尝试加载。

这样的好处是:java类随着它的类加载器一起具备了带有优先级的层次关系.这是十分必要的,比如java.langObject,它存放在\jre\lib\rt.jar中,它是所有java类的父类,因此无论哪个类加载都要加载这个类,最终所有的加载请求都汇总到顶层的启动类加载器中,因此Object类会由启动类加载器来加载,所以加载的都是同一个类,如果不使用双亲委派模型,由各个类加载器自行去加载的话,系统中就会出现不止一个Object类,应用程序就会全乱了。

四、源码解析

1.定义和属性

是一个抽象类:public abstract class ClassLoader

父加载器属性:private final ClassLoader parent;

2.常用方法

defineClass(String name, java.nio.ByteBuffer b,ProtectionDomain protectionDomain)

指定保护域(protectionDomain),把ByteBuffer的内容转换成 Java 类,这个方法被声明为final的。

defineClass(String name, byte[] b, int off, int len)

把字节数组 b中的内容转换成 Java 类,其开始偏移为off,这个方法被声明为final的。

findClass(String name)

查找指定名称的类


loadClass(String name)

加载指定名称的类

resolveClass(Class<?>)

链接指定的类

其中 defineClass 方法用来将 字节流解析成 JVM 能够识别的 Class 对象,有了这个方法意味着我们不仅仅可以通过 class 文件实例化对象,还可以通过其他方式实例化对象,如果我们通过网络接收到一个类的字节码,拿到这个字节码流直接创建类的 Class 对象形式实例化对象。如果直接调用这个方法生成类的 Class 对象,这个类的 Class 对象还没有 resolve ,这个 resolve 将会在这个对象真正实例化时才进行。

defineClass 通常是和findClass 方法一起使用的,我们通过覆盖ClassLoader父类的findClass 方法来实现类的加载规则,从而取得要加载类的字节码,然后调用defineClass方法生成类的Class 对象,如果你想在类被加载到JVM中时就被链接,那么可以接着调用另一个 resolveClass 方法,当然你也可以选择让JVM来解决什么时候才链接这个类。

五、总结

Java装载类使用“全盘负责委托机制”。“全盘负责”是指当一个ClassLoder装载一个类时,除非显示的使用另外一个ClassLoder,该类所依赖及引用的类也由这个ClassLoder载入;“委托机制”是指先委托父类装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。这一点是从安全方面考虑的,试想如果一个人写了一个恶意的基础类(如java.lang.String)并加载到JVM将会引起严重的后果,但有了全盘负责制,java.lang.String永远是由根装载器来装载,避免以上情况发生 除了JVM默认的三个ClassLoder以外,第三方可以编写自己的类装载器,以实现一些特殊的需求。类文件被装载解析后,在JVM中都有一个对应的java.lang.Class对象,提供了类结构信息的描述。数组,枚举及基本数据类型,甚至void都拥有对应的Class对象。Class类没有public的构造方法,Class对象是在装载类时由JVM通过调用类装载器中的defineClass()方法自动构造的。

参考资料:

    1. 五分钟看懂ClassLoader - 简书
    2. 深入理解ClassLoader工作机制(jdk1.8)_zthgreat的博客-CSDN博客
    3. 【JVM】深度分析Java的ClassLoader机制(源码级别) - 风动静泉 - 博客园
    相关文章
    |
    13天前
    |
    安全 前端开发 Java
    JDK源码级别彻底剖析JVM类加载机制
    JDK源码级别彻底剖析JVM类加载机制
    |
    13天前
    |
    缓存 Dubbo Java
    趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
    趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
    |
    8月前
    |
    Java 容器
    阿里内部流传的JDK源码剖析手册!GitHub已获上千万的访问量
    相信现在已经有很多小伙伴知道了“微软”要对JDK下手了! JDK是什么? jdk是Java语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。jdk是整个java开发的核心,它包含了JAVA的运行环境和JAVA工具。相对而言,没有jdk的话,无法编译Java程序(指java源码.java文件),如果想只运行Java程序(指class或jar或其它归档文件),要确保已安装相应的JRE。
    211 0
    |
    13天前
    |
    缓存 Java Spring
    Spring 源码阅读 66:基于 JDK 的 AOP 代理如何获取拦截器链(4)- 将 Advice 封装为拦截器
    【1月更文挑战第1天】本文分析了 Advice 被封装成 MethodInterceptor 的过程,Spring AOP 用到的五种 Advice 中,有些本身就是 MethodInterceptor 的实现类,而有些需要通过适配器的封装。
    48 0
    |
    8月前
    |
    设计模式 Java 程序员
    太爆了!阿里最新出品2023版JDK源码学习指南,Github三天已万赞
    最近后台收到很多粉丝私信,说的是程序员究竟要不要去读源码?当下行情,面试什么样的薪资/岗位才会被问到源码? 对此,我的回答是:一定要去读,并且要提到日程上来! 据不完全统计,现在市面上不管是初级,中级,还是高级岗,面试的时候都有可能会问到源码中的问题,它已经成为程序员常规必备的一个技术点。如果你当下想通过一个面试,或者想把中级薪资要到相对于比较高的话,源码这块就必须要会。
    103 0
    |
    13天前
    |
    算法 Java 索引
    【数据结构与算法】4、双向链表(学习 jdk 的 LinkedList 部分源码)
    【数据结构与算法】4、双向链表(学习 jdk 的 LinkedList 部分源码)
    36 0
    |
    13天前
    |
    设计模式 Java
    根据JDK源码Calendar来看工厂模式和建造者模式
    根据JDK源码Calendar来看工厂模式和建造者模式
    |
    13天前
    |
    Java Linux iOS开发
    Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
    Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
    26 0
    |
    13天前
    |
    XML Java 数据格式
    Spring 源码阅读 70:基于 JDK 的 AOP 代理拦截器链执行(4)- 容易被忽略的 ExposeInvocationInterceptor
    【1月更文挑战第5天】本文分析了 Spring AOP 拦截器链中的一个特殊拦截器 ExposeInvocationInterceptor 的注册的时机以及它的作用。至此,基于 JDK 的 AOP 代理拦截器链执行的逻辑就分析完了。
    464 0
    |
    13天前
    |
    Java 索引 Spring
    Spring 源码阅读 69:基于 JDK 的 AOP 代理拦截器链执行(3)- MethodInterceptor 分析
    【1月更文挑战第4天】本文详细分析了 Spring AOP 中五种增强类型对应的拦截器中增强方法的执行逻辑,结合上一篇中分析的 ReflectiveMethodInvocation 中proceed方法的执行逻辑,就组成了完整的拦截器链递归调用的逻辑。
    36 0