黑马程序员JVM系列学习——Java类的生命周期

本文详细解释了Java类加载的三个主要阶段:加载阶段将类信息保存在方法区和堆中的Class对象;连接阶段包括验证、准备和解析;初始化阶段执行静态代码块并为final变量赋值。特别强调了静态代码块和非静态代码块的执行顺序。
摘要由CSDN通过智能技术生成

一、加载阶段

首先类加载器通过不同渠道加载类,加载后Java虚拟机将字节码中的信息保存到方法区中,生成一个InstanceKlass对象,保存类的所有信息。

同时,Java虚拟机会在堆中生成一份与方法区中数据类似的java.lang.Class对象(反射时获取的对象,详见Java进阶——反射篇),作用是在Java代码中去获取类的信息以及存储静态字段的数据(JDK8之后静态数据存放在堆中)。

 二、连接阶段

1.验证,验证内容是否满足Java虚拟机规范

(1)文件格式验证,是否以魔数CAFEBABE开头,及主次版本是否满足当前Java虚拟机版本要求

(2)元信息验证,如一个类必须有父类(即使程序员不继承也会默认继承java.lang.object)

(3)验证程序执行指令的语义,如方法内的指令跳转到不正确的位置

(4)验证符号引用,如是否访问了其他类中的private方法等

2.准备,给静态变量分配内存并赋初值

在堆区给静态变量分配内存并分配一个默认初始值,如int为0,boolean为false,引用类型为null等(与设定值无关,设定值发生在初始化阶段)

若该值被finnal修饰,则初始化时直接初始化为设定的值。(final相当于const,值不可改变,方法不能重写,声明的类不能被继承)

3.解析,将常量池中符号引用替换成指向内存的直接引用(即将符号引用改变为内存地址)

三、初始化阶段

执行静态代码块中的代码,并为静态变量赋值

对象数组的创建不会导致数组中的元素的类进行初始化。

final修饰的变量如果赋值的内容需要执行指令才能得出结果,会调用clinit方法进行初始化。

对于静态代码块:

静态代码块会在类的初始化阶段被执行,有多个静态代码块则按顺序执行。

无论是否创建此类的对象,只要加载、连接、初始化,静态代码块都会被调用。

非静态代码块:即无static,只有{ }里面的代码块,会被当作类的构造器的一部分执行,有多个则按顺序,且执行顺序优先于构造器。

如上图,init方法即构造方法,先执行非静态代码块,然后执行构造方法。

clinit即classinit,在类的初始化中执行的,该方法中为类中的静态代码块,按顺序执行。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值