首页 > 其他 > 详细

类的生命周期

时间:2021-02-28 00:24:34      阅读:32      评论:0      收藏:0      [点我收藏+]

类的生命周期包括如下7个阶段:

技术分享图片

加载的理解

所谓加载,简而言之就是将Java类的字节码文件加载到机器内存中,并在内存中构建出Java类的原型--类模板对象。

类模板对象--其实就是在Java类在JVM内存中的一个快照,JVM将从字节码文件中解析出的常量池,类字段,类方法等信息存储到类模板中,这样JVM在运行期便能通过类模板而获取Java类中的任意信息,能够对Java类的成员变量进行遍历,也能进行Java方法的调用

加载完成的操作

加载阶段,简而言之,查找并加载类的二进制数据,生成Class的实例。

技术分享图片

验证阶段

当类加载到系统后,就开始链接操作,验证是链接操作的一部分

  • 目的是保证加载的字节码是合法的、合理并符合规范的

大体上Java虚拟机需要做以下检查:

技术分享图片
  • 其中格式验证会和加载阶段一起执行。验证通过之后,类加载器才会成功将类的二进制数据信息加载到方法区中
  • 格式验证之外的验证操作将会在方法区中进行

准备阶段

简而言之,就是为类的静态变量分配内存,并将其初始化为默认值

  • 注意:
    • 这里不包含基本数据类型的字段用static final修饰的情况,因为final在编译的时候就会分配了,准备阶段会显式赋值

解析阶段

简而言之,将类,接口,字段和方法的符号引用转为直接引用

在HotSpot VM中,加载,验证,准备和初始化会按照顺序有条不紊的执行,但链接阶段中的解析操作往往会伴随着JVM在执行完初始化之后再执行

初始化阶段

> 简而言之,就是为类的静态变量赋予正确的初始值
> 执行类构造器<clinit>()方法的过程

> 当初始化一个类的时候,如果发现其父类还没进行初始化,则需要先触发器父类的初始化

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

使用 static + final 修饰,且显式赋值中不涉及到方法或构造器调用的基本数据类型或String类型的显式赋值,是在准备阶段进行赋值

什么时候会发生类初始化?

  • 类的主动引用(一定会发生类的初始化)
    • 当虚拟机启动,先初始化main方法所在的类
    • new一个类的对象
    • 调用类的静态成员和静态方法
    • 使用java.lang.reflect包的方法对类进行反射调用
    • 当初始化一个类,如果其父类没有被初始化,则会先初始化它的父类
  • 类的被动引用
    • 当访问一个静态域时,只有真正声明这个域的类才会被初始化。如:当通过子类引用父类的静态变量,不会导致子类初始化
    • 通过数组定义类引用,不会触发此类的初始化
    • 引用常量不会触发此类的初始化(常量在链接阶段就存入调用类的常量池中了)

类的生命周期

原文:https://www.cnblogs.com/LongDa666/p/14457133.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!