类的生命周期

概要

一个类从出生到死亡会经历五个阶段:加载、连接、初始化、使用、卸载,其中连接又分为验证、准备和解析。加载、连接、初始化这三个阶段(类加载过程)是必定会执行,而使用和卸载不一定执行。

在这里插入图片描述

加载(Loading)

加载顾名思义就是将类加载到jvm中,在堆区中实例化一个java.lang.Class对象,作为方法区中类入口。
一般会有一下几种方式将类加载到内存中:
1.通过类的全限定名来获取类的class文件,再读取二进制流信息
2.从jar文件中读取
3.通过一定规则实时生成,例如设计模式中的动态代理

连接(Linking)

连接分为验证,准备和解析。

  1. 验证中的工作主要是验证类的合法性。如字节码格式,变量与方法的合法性、数据类型的有效性、继承与实现的规范性等,确保加载到内存中能够正常运行
  2. 准备主要是为类的静态变量分配内存并赋默认值,而非静态变量不会分配内存。值得注意的是,静态变量的赋值是默认值,而非程序设定的值,例如静态int类型的age字段,在准备阶段会被赋值为0,而真正的赋值程序设定的值是在初始化阶段
  3. 解析则是将常量池中的符号引用、方法区中的字符引用解析为直接引用(即将字符解析成计算机认识的二进制)

初始化(Initialization)

类初始化是类加载的最后一步,该阶段才开始真正执行程序代码,之前的动作都由虚拟机主导。
jvm对类加载时机没有明确规定,但对类的初始化有着明确规范:只有当类被直接引用的时候,才会触发类的初始化。类的直接引用有以下几种:

  1. new关键字创建对象
  2. 读取或设置类的静态变量
  3. 调用类的静态方法
  4. 通过反射动态获取类的行为
  5. 初始化子类会初始化父类
  6. 作为程序入口(mian方法)直接运行时
  7. 接口实现类初始化时,会触发直接或间接实现所有接口的初始化

类的初始化,会自上而下运行静态代码块或静态赋值语句,非静态与非赋值的静态语句不会执行 ;
如果存在父类,会优先初始化父类,这是一个典型的递归模型。
区别于对象的初始化,类的初始化所做的一起都是基于类变量或类语句的,也就是说执行的都是共性的抽象信息。而我们知道,类就是对象实例的抽象。

使用(Using)

类的使用分为直接引用和间接引用。
直接引用与间接引用等判别条件,是看对该类的引用是否会引起类的初始化
直接引用已经在类的初始化中的有过阐述,不再赘述。而类的间接引用,主要有下面几种情况:

  1. 当引用了一个类的静态变量,而该静态变量继承自父类的话,不引起初始化
  2. 定义一个类的数组,不会引起该类的初始化;
  3. 当引用一个类的的常量时,不会引起该类的初始化

卸载(Unloading)

当类使用完了之后,类就要进入卸载阶段了。那何为衡量类使用完的标准呢?
5. 该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。
6. 加载该类的ClassLoader已经被回收。
7. 该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。
如果以上三个条件全部满足,jvm就会在方法区垃圾回收的时候对类进行卸载,类的卸载过程其实就是在方法区中清空类信息,java类的整个生命周期就结束了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值