JVM深入学习-1.2 通过一道题理解class文件加载到内存的过程

上代码:

public class InitialOrder {
    private static int i = 2;
    private static InitialOrder obj = new InitialOrder();

    public InitialOrder() {
        i ++;
    }

    public static void main(String[] args) {
        System.out.println(InitialOrder.i);
    }
}

情况1:如果按照上面代码,直接运行,打印结果为 3。读者可以试一试。

情况2:第一个属性和第二个属性代码顺序调换一下,打印结果为 2。

这就和class文件的加载过程有关系了。

class文件加载过程:class加载 → verification → prepare → resolve → initializing

主要说说 prepare 和 initializing阶段。

prepare:主要是给静态属性赋值。

initializing:主要是给实例赋值。

分析情况1:在main方法中打印 i 的值时,首先java文件需要编译成class文件,加载的class文件需要经过class文件格式的验证,然后进入静态属性初始化阶段,这个时候 i = 0,obj = null。再进入resolve阶段把符号引用解析为直接引用,进入到 initializing 阶段,需要给实例初始化值,这个时候先初始化 i = 2 ,再初始化 obj = new InitialOrder() ,obj 生成对象的时候调用了构造函数,构造函数中有 i++ 操作,原本 i = 2,i ++ 指令执行后,i = 3。所以情况1打印结果为3。

分析情况2:加载class文件到prepare阶段时,静态属性赋值,obj = null,i = 0,加载到 initializing 阶段,obj = new InitialOrder(),obj 生成对象的时候调用了构造函数,构造函数中有 i++ 操作,原本 i = 0,i ++ 指令执行后,i = 1。按照代码顺序给 i 赋值,这个时候又把 2 赋值给 i 。所以打印结果为 2。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荆茗Scaler

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值