jvm类的装载过程浅析

本文详细阐述了Java虚拟机(JVM)将类的装载过程分为装载、链接和初始化三个步骤,以及各步骤的具体操作。从装载阶段如何找到二进制字节码并加载至JVM,到效验阶段对二进制字节码格式进行验证,再到准备阶段为类变量分配内存并设置默认值,直至解析阶段(可选)在类的常量池中寻找符号引用并将其替换为直接引用。文章最后解释了初始化阶段如何为类或接口首次主动使用时赋予正确的值,以及主动使用的情况和条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

jvm将类的装载过程分为3个步骤:装载,链接,初始化。而链接过程又分为:效验,准备,解析(可选)
1,[b]装载[/b]
负责找到二进制字节码并加载至jvm,jvm通过类的全限定名及类的加载器完成类的加载
2,[b]效验[/b]
对二进制字节码的格式进行效验
3,[b]准备[/b]
jvm为类变量分配内存,并设置默认初始值(譬如 reference设置为null boolean设置为false)
4,[b]解析[/b](可选)
在类的常量池中寻找类,接口,字段,方法的符号引用,并把它替换为直接引用,在符号引用被程序首次主动使用之前,解析这个步骤是可选的
5,[b]初始化[/b]
为了准备让一个类或者接口首次主动使用,就要为类变量赋予正确的值(注意哦:是正确的值,不是默认值)。
什么是主动使用呢?6种活动被认为是主动使用
[list]
[*] (1) 调用了new。
[*] (2) 调用了类中的静态方法。
[*] (3) 调用了类中的非常量的静态字段。
[*] (4) 反射。
[*] (5) 子类的初始化方法。
[*] (6) jvm启动过程中指定的初始化类。
[/list]
其中对于非常量的静态字段的调用还有一个条件是只有当类或者接口中的确声明了这个字段才被认为是主动使用,而对于子类或者实现接口调用父类的非常量的静态字段被认为是被动使用,不会触发初始化。如下:
public class Parent {


static int parent=(int) (Math.random()*3.0);
static {
System.out.println("老子出生了!!!");
}
}

public class Baby extends Parent {

static int baby=(int) (Math.random()*6.0)+2;
static {
System.out.println("老子经过不懈的努力,儿子也出生了~!!!");
}
}

public class Test {


public static void main(String[] args) {
int test=Baby.parent;
System.out.println(test);
}
static{
System.out.println("见证人上帝出世了!!!");
}
}


结果为:
见证人上帝出世了!!!
老子出生了!!!
1


parent是类Parent的非常量静态字段,Baby.parent触发了Parent的初始化,而Baby没有被初始化,也没有被加载。

而对于final static的字段,使用这样的字段,也不触发初始化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值