博客
关于我
2. 类的加载机制
阅读量:798 次
发布时间:2023-04-02

本文共 1208 字,大约阅读时间需要 4 分钟。

类的加载机制概述

Java虚拟机通过将描述类的数据从Class文件加载到内存,并进行验证、转换、解析和初始化,最终形成可直接使用的Java类类型,这一过程称为类的加载机制。Class文件不仅代表Java语言中的类或接口,其实是一串二进制字节流,可能来源于本地磁盘、网络、数据库、内存或动态生成。


类加载的时机与生命周期

类的生命周期包括七个阶段:加载、验证、准备、解析、初始化、使用和卸载。其中验证、准备和解析统称为连接阶段。需要注意的是,生命周期中的“加载”指的是将Class文件加载到内存,而不是类加载机制中的加载。

类的主动引用有六种情况:

  • new一个对象或访问static属性(非final类型除外)或方法。
  • 使用反射时,如果类型已被初始化,则需先初始化。
  • 初始化类时发现父类未初始化,则需先初始化父类。
  • 虚拟机启动时初始化主类(包含main方法)。
  • JDK7引入的动态语言支持。
  • 接口定义默认方法的实现类初始化时,需先初始化接口。
  • 被动引用不会引起类初始化,例如通过子类引用父类静态字段时只会初始化父类。


    类加载过程详解

    1. 加载阶段

    加载阶段完成以下三项:

  • 通过类全限定名获取二进制字节流。
  • 将字节流转化为方法区运行时数据结构。
  • 生成java.lang.Class对象作为类的数据访问入口。
  • 2. 验证阶段

    验证确保Class文件符合虚拟机要求。包括:

  • 文件格式验证。
  • 元数据验证(检查类继承关系和接口实现)。
  • 字节码验证(检查语义正确性)。
  • 符号引用验证(检查引用的类字段可访问性)。
  • 3. 准备阶段

    为类静态变量分配内存并初始化为零值。注意:final static常量在编译时已转化为具体值,不会在准备阶段初始化。

    4. 解析阶段

    待解决。

    5. 初始化阶段

    执行clinit方法,赋值静态变量并执行静态代码块。注意事项:

  • clinit方法由编译器自动生成。
  • 静态语句块只能访问前定义变量,不能赋值。
  • 虚拟机确保子类clinit执行前父类已初始化。
  • 如果无静态代码块或静态变量赋值操作,则无clinit方法。
  • 初始化过程需线程安全,防止多线程竞争。

  • 类加载器

    类加载器负责将Class文件加载到内存,全类名和类加载器共同确立唯一性。从Java虚拟机角度,存在两种加载器:引导类加载器(C++实现)和其他类加载器(Java实现,继承ClassLoader)。从程序员角度,分为启动类加载器、扩展类加载器和应用程序类加载器。

    启动类加载器加载核心类库和其他加载器;扩展类加载器加载扩展目录下的类;应用程序类加载器加载用户类路径。


    双亲委派机制

    双亲委派机制防止核心API篡改。具体实现:

  • 当一个类加载器收到加载请求时,委托上一级加载器执行。
  • 如果上级完成加载,返回;否则自行加载。
  • 优势:确保核心类如java.lang.Object无法篡改,因为这些类由引导类加载器加载。


    破坏双亲委派模型

    待解决。

    转载地址:http://yxefk.baihongyu.com/

    你可能感兴趣的文章