Java中的类加载机制

类加载过程

类从加载到卸载为止,生命周期包括:加载(Loading)→验证(Preparation)→解析(Resolution)→初始化(Initialization)→使用(Using)→卸载(UnLoading)。

其中验证准备解析三个部分称为链接(Linking)。

类加载时机

类加载时机有且只有以下情况:

  • 遇到 new、getstatic、putstatic、invokestatic 这四条字节码指令时,如果类没有进行初始化,则会进行初始化
  • 使用反射机制包中的方法对类进行发射调用的时候,如果类没有进行初始化,则会进行初始化
  • 当初始化一个类的时候,若其父类没有被初始化,则先进行父类初始化
  • 包含main方法的类会先进行初始化

父类与子类初始化

在类加载时机中的第三点,提到了父类和子类的初始化,这里详细的再介绍一下内部顺序:

  • 初始化 父类 静态变量和静态代码块
  • 初始化子类的静态变量和静态代码块
  • 初始化 父类的实例变量、实例代码块和构造方法
  • 初始化子类的实例变量、实例代码块和构造方法

类加载的加载阶段

加载类加载不同,加载是类加载的过程之一。

加载阶段会生成Class对象,且用户可以使用系统提供的类加载器来完成,也可以由用户自定义的类加载器去完成。这里和类加载器有关,详情戳主页。

加载阶段,JVM完成三件事情:

  • 通过类的全限定名来获取此类的二进制字节流
  • 将字节流所代表的静态存储结构转化为方法区的运行时数据结构
  • 在Java堆中生成Class对象,作为访问入口

类加载的链接阶段

链接阶段分为: 验证、准备和解析 三个阶段

验证

验证是链接的第一步,目的是确保Class文件字节流中包含的信息符合虚拟机的要求,不会危害虚拟机自身的安全。

主要验证以下几个方面:

  • 文件格式验证:验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理
  • 元数据验证:对字节码描述的信息进行语义分析,以确保其信息符合Java语言规范的要求,保证不存在不符合Java语言规范的元数据信息
  • 字节码验证进行数据流和控制流分析,保证被校验类的方法在运行时不会做出危害虚拟机的行为
  • 符号引用验证将符号引用转化为直接引用,可以看作是对类自身以外(常量池中各种符号的引用)的信息进行匹配性的校验。保证解析动作能正常执行。

总结:验证字节码的正确性

准备

准备阶段是正式为类变量(被static修饰的变量)分配内存并设置变量初始值的阶段,这些内存将在方法区中分配。实例变量分配内存将在初始化时和对象一起分配到堆区初始值通常情况下是数据类型的零值

总结:主要是针对静态变量,进行内存分配和给默认零值

基本数据类型的零值:

数据类型零值
int0
long0L
short(short)0
char‘\u0000’
byte(byte)0
booleanfalse
float0.0f
double0.0d
referencenull

解析

解析阶段是虚拟机将常量池内符号引用替换为直接引用的过程。解析主要针对于类或接口、字段、类方法、接口方法四种。

总结:将所有符号引用替换为方法区原始引用

类加载的初始化阶段

类初始化阶段是类加载过程的最后一步,到了初始化阶段,才开始真正执行类中定义的Java程序代码(字节码)。此时 静态变量被赋值,静态代码块会被执行


更多有关Java基础内容,详戳【Java基础】,其他内容,详戳主页。资料参考【深入理解Java虚拟机——周志明版】。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值