一道题彻底搞懂Java类的加载顺序

源码

建议先给出自己的答案,不要复制然后去运行,这样就没有意义。出现错误也没有关系。

public class Main {
    private static int k = 1;
    private static Main m1 = new Main("m1");
    private static Main m2 = new Main("m2");
    private static int i = print("i");
    private static int n = 99;
    {
        print("初始化块");
        j = 100;
    }
    public Main(String name) {
        System.out.println((k ++) + ":" + name + ",i=" + i + ",n=" + n);
        ++ i;
        ++ n;
    }
    static {
        print("静态块");
        n = 100;
    }
    private int j = print("j");
    public static int print(String str) {
        System.out.println((k ++) + ":" + str + ",i=" + i + ",n=" + n);
        ++ n;
        return ++ i;
    }

    public static void main(String[] args) {
        Main m = new Main("m");
    }
}

输出结果

在这里插入图片描述

解释

这道题还是有点难度的,答案错了也没关系。耐心看完这篇博客就什么明白了。

  1. 首先我们需要清除当类加载时,第一步是静态的属性进行创建,此时并不会进行赋值操作,也即k=0,m1=null,m2=null等等
  2. 然后才是开始进行赋值操作,此时k=1;接下来创建实例对象m1,创建对象时是执行所有的非静态属性、代码块以及方法,最后执行构造方法。此时执行第一个静态代码块,并且此时的i和n是还没有赋值的,所以输出1:初始化块,i=0,n=0",然后i和n都完成++操作。
  3. 然后执行private int j = print("j");,故而输出2:j,i=1,n=1,i和n也都完成++操作。
  4. 当所有的非静态属性、方法等都执行完毕,就执行自己的构造函数,故而输出3:m1,i=2,n=2,i和n也都完成++操作。
  5. 此时完成了m1对象的创建。代码继续向下执行,创建m2对象,其过程同m1对象的过程一样,先完成非静态的所有属性、代码块、方法,然后再执行构造函数。这里就不作过多赘述。
  6. 当m2对象也创建完成,代码继续向下执行,对i进行赋值操作,也就是执行print("i"),故而输出7:i,i=6,n=6,i和n也都完成++操作。
  7. 接着向下执行,为n赋值为99。然后是静态代码块static{print("静态块");n = 100;}这里要注意静态代码块也是赋值操作。因此输出8:静态块,i=7,n=99
  8. 然后就是执行我们的main方法,跟创建m1和m2时一样,只不过此时的n以及完成了赋值操作。

总结起来就一句话,类加载时先静态,并且按照顺序从上往下加载,先进行所有静态属性的初始化,然后才是赋值。创建对象时,只执行非静态的,然后再执行构造方法。

到这里就已经结束了。需要多理解几遍,如果觉得自己已经吃透了,就可以修改一下k和n的初始值,并且打印一下y然后验证自己的结果。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值