浅聊类加载


一、流程

Java 源码需要先进行编译,将编译之后所得的字节码文件交给 Java 虚拟机进行解析,将字节码转换成当前平台(Windows、Mac、Linux…)能识别的机器指令。
在这里插入图片描述
也就是说要想执行下去,首先得获取 Class 文件,而获取 Class 文件的过程,便是所谓的类加载

类加载指的是将源码( Xx.java )经过 Javac 编译之后所得到的字节码文件( Xx.class )从硬盘上加载到内存的过程。

类加载主要三步:加载 Loading连接 Linking 初始化 Initialization
其中连接又分为验证、准备和解析三个阶段。
在这里插入图片描述

二、加载

利用类加载器将 class 字节码文件加载并解析到内存,将字节码中的信息转变为方法区的运行时数据结构,方法区会存储包括类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据,并且会在堆上生成一个代表该类的 Class 对象,作为方法区数据的访问入口
在这里插入图片描述

三、连接

将字节码文件合并到 JVM 的运行环境之中(JRE)

注意:加载和连接是交叉进行的,连接可能在加载还未结束便开始了

3.1 验证

目的:确保 Class 字节码文件中的信息符合 JVM 的规范,确保这些信息执行后不会存在安全问题、危害虚拟机。

主要由四个检验阶段组成

  • 文件格式验证
    • 对 Class 文件格式的检查,确保符合 Class 文件的规范
    • 基于 Class 文件进行
  • 元数据验证
    • 对字节码语义的检查
    • 比如:是否继承了不能继承的类…
    • 基于方法区的存储结构进行
  • 字节码验证
    • 对程序语义的检查
    • 比如:参数是否正确、对象转型是否正确、
    • 基于方法区的存储结构进行
  • 符号引用验证
    • 对类的正确性的检查
    • 比如:引用其他类、方法是否存在,是否能正常访问
    • 基于方法区的存储结构进行

3.2 准备

在方法区中为类变量(被 static 修饰的)分配内存,并设置初始值,如果未手动设置,则将变量的类型对应的默认值作为初始值,反之则是由手动设置的作为初始值

3.3 解析

虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。

换句话来说,就是得到类或者字段、方法在内存中的指针或者偏移量,能直接定位到虚拟机,内存中具体的位置,从而使得方法可以被调用。

主要针对:类或接口字段类方法接口方法方法类型方法句柄调用限定符 7 类符号引用进行。

四、初始化

源码被编译后,会自动生成一个类构造器< clinit > ()方法(类构造器是构造类的信息而不是构造对象的构造器

初始化便是执行初始化方法 < clinit >() 方法进行初始化的的过程,此时才是正在执行字节码。如果父类没有初始化,会先触发父类的初始化,然后才是子类。

特点

  • 虚拟机会保证一个类的 < clinit > () 方法在多线程的环境下被正确加锁和同步,保证的安全性。( < clinit > () 带锁

4.1 主动引用

一定会发生类的初始化

  • 虚拟机启动,初始化 main 方法的类
  • new 对象
  • 调用类的静态成员(除 final 常量)和静态方法
  • 对类进行反射调用

4.2 被动引用

不会发生类的初始化

  • 访问一个静态域时,只有定义该静态域的类会被初始化,如通过子类访问父类的静态变量,子类不会初始化
  • 引用常量不会触发类的初始化
  • 数组定义类引用不会触发对应类的初始化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值