类的加载机制详解

一、类的加载过程

一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历以下几个阶段

  • 加载(Loading):

    1. 通过一个类的全限定名来获取定义此类的二进制字节流(可以通过class文件、网络等任何途径)
    2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
    3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
  • 验证(Verification):

    1. 文件格式验证,验证文件是否符合class文件格式
    2. 元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合《Java语言规范》的要求。
    3. 字节码验证:通过数据流分析和控制流分析,确定程序语义是合法的、符合逻辑的,保证被校验类的方法在运行时不会做出危害虚拟机安全的行为。
    4. 4.符号引用验证:验证该类是否缺少或者被禁止访问它依赖的某些外部类、方法、字段等资源。如果无法通过符号引用验证,Java虚拟机将会抛出一个java.lang.IncompatibleClassChangeError的子类异常,典型的如:java.lang.IllegalAccessError、java.lang.NoSuchFieldError、java.lang.NoSuchMethodError等。
  • 准备(Preparation):准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段,这时候进行内存分配的仅包括类变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。这个时候的初始值指的是数据类型的默认值,不是我们编码定义的那个值。

  • 解析(Resolution):解析阶段是Java虚拟机将常量池内的符号引用替换为直接引用的过程

  • 初始化(Initialization):根据程序员通过程序编码制定的主观计划去初始化类变量和其他资源。至此之后,类才会交给应用程序使用。

二、类加载器

对于任意一个类,都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间。再通俗的说法就是两个类来源于同一个Class文件,被同一个Java虚拟机加载,只要加载它们的类加载器不同,那这两个类就必定不相等。

类加载器分类:

  • 启动类加载器(Bootstrap ClassLoader):这个类加载器使用C++语言实现。这个类加载器负责加载存放在<JAVA_HOME>\lib目录,或者被-Xbootclasspath参数所指定的路径中存放的。启动类加载器无法被Java程序直接引用,用户在编写自定义类加载器时,如果需要把加载请求委派给引导类加载器去处理,那直接使用null代替即可。当使用class对象的getClassLoader 得到null 说明使用的是这个加载器。

  • 扩展类加载器(Extension Class Loader):这个类加载器是在类sun.misc.Launcher$ExtClassLoader中以Java代码的形式实现的。它负责加载<JAVA_HOME>\lib\ext目录中,或者被java.ext.dirs系统变量所指定的路径中所有的类库。我们可以将具有通用性的类库放置在ext目录里以扩展Java SE的功能,也可以直接在程序中使用扩展类加载器来加载Class文件。

  • 应用程序类加载器(Application Class Loader):这个类加载器由sun.misc.Launcher$AppClassLoader来实现。由于应用程序类加载器是ClassLoader类中的getSystem-ClassLoader()方法的返回值,所以有些场合中也称它为“系统类加载器”。它负责加载用户类路径(ClassPath)上所有的类库,开发者同样可以直接在代码中使用这个类加载器。如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

双亲委派模型

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载。总结就是先自下而上查找,最顶层加载器都查找不到,然后开始自上而下加载,最后加载不到抛出异常。
为什么这么设计呢?由上面我们知道不同类加载器即使加载的是同一个class文件,类也不相等,如果没有双亲委派,同一个class文件会有很多类型,造成程序混乱。

三、类加载器的应用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值