Java类加载器

1.Java类加载器

在上一篇博客中,我已经详细总结了java类的加载过程,今天总结了一下类的加载器。类的加载器的作用就是通过类的全限定名来读取此类二进制字节流打jvm中,然后转换为一个java.lang.class对象实例。在虚拟机中提供了3种类加载器,引导(Bootstrap)类加载器,扩展(Extension)类加载器,系统(System)类加载器(也称应用类加载器)。

引导类加载器(Bootstrap Class LOader)

它用来加载Java的核心库,是用C++语言实现的,是虚拟机自身的一部分,并不继承子java.lang.ClassLoader。

扩展类加载器(Extension Class loader)

它用来加载Java的拓展库。Java虚拟机的实现会提供一个扩展目录。该类加载器在此目录里面查找并加载java类,开发者可以直接使用标准扩展类加载器。

系统类加载器(System class loader)

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

除了系统提供的类加载器外,开发人员可以通过继承java.lang.ClassLoader类的方法实现自己的类加载器,以满足一些特殊要求。

类加载器树状组织结构示意图(箭头指向的是父类加载器)

 

2.类加载器的代理模式

类的加载器在尝试自己去查找某个类的字节码并定义它时,会代理给其父亲加载器,由父类加载器去尝试加载它,依次类推。在介绍代理模式背后的动机之前,首先需要说明一下 Java 虚拟机是如何判定两个 Java 类是相同的。 Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。 只有两者都相同的情况,才认为两个类是相同的。即便是同样的字节代码,被不同的类加载器加载之后所得到的类,也是不同的。

了解了这一点之后,就可以理解代理模式的设计动机了。代理模式是为了保证 Java 核心库的类型安全。所有 Java 应用都至少需要引用 java.lang.Object类,也就是说在运行的时候,java.lang.Object这个类需要被加载到 Java 虚拟机中。如果这个加载过程由 Java 应用自己的类加载器来完成的话,很可能就存在多个版本的 java.lang.Object类,而且这些类之间是不兼容的。通过代理模式,对于 Java 核心库的类的加载工作由引导类加载器来统一完成,保证了 Java 应用所使用的都是同一个版本的 Java 核心库的类,是互相兼容的。

3.加载类的过程

前面介绍类加载器的代理模式的时候,提到过类加载器会首先代理给其它类加载器来尝试加载某个类。这就意味着真正完成类的加载工作的类加载器和启动这个加载过程的类加载器,有可能不是同一个。真正完成类的加载工作是通过调用 defineClass来实现的;而启动类的加载过程是通过调用 loadClass来实现的。前者称为一个类的定义加载器(defining loader),后者称为初始加载器(initiating loader)。在 Java 虚拟机判断两个类是否相同的时候,使用的是类的定义加载器。也就是说,哪个类加载器启动类的加载过程并不重要,重要的是最终定义这个类的加载器。两种类加载器的关联之处在于:一个类的定义加载器是它引用的其它类的初始加载器。如类 com.example.Outer引用了类 com.example.Inner,则由类 com.example.Outer的定义加载器负责启动类 com.example.Inner的加载过程。

方法 loadClass()抛出的是 java.lang.ClassNotFoundException异常;方法 defineClass()抛出的是 java.lang.NoClassDefFoundError异常。

类加载器在成功加载某个类之后,会把得到的 java.lang.Class类的实例缓存起来。下次再请求加载该类的时候,类加载器会直接使用缓存的类的实例,而不会尝试再次加载。也就是说,对于一个类加载器实例来说,相同全名的类只加载一次,即 loadClass方法不会被重复调用。

这里介绍的只是java中一些类加载器,其实虚拟机在真正的加载中远比这个复杂,一些加载机制和模式也是目前一些流行的框架也是基于这些开发的。

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值