类实例化代码的执行顺序及特例情况

在java中正常的实例化逻辑为:

  • 父类的静态变量赋值
  • 自身的静态变量赋值
  • 父类成员变量赋值和父类块赋值
  • 父类构造函数赋值
  • 自身成员变量赋值和自身块赋值
  • 自身构造函数赋值

具体的使用可以参考这篇博客:Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序
但是会有特殊情况比如下面这个class的执行情况:

public class StaticTest {
    static StaticTest st = new StaticTest();

    static {
        System.out.println("1");
    }

    {
        System.out.println("2");
    }

    StaticTest() {
        System.out.println("3");
        System.out.println("a=" + a + ",b=" + b + ",c=" + c);
    }

    int a = 110;
    static int b = 111;
    static final int c = 112;

    public static void staticFunction() {
        System.out.println("4");
    }

    public static void main(String[] args) {
        staticFunction();
    }
}

这个例子的输出结果为:
2
3
a=110,b=0,c=112
1
4
为什么会出现这种结果哪,可以看下这篇博客:哥们,你真以为你会做这道JVM面试题?,在这篇博客里面作者分析了为什么会出现这种结果,这里自己再啰嗦几句,将自己的理解用于梳理一下为何会出现这种结果。
首先引一张图就是类的生命周期:
在这里插入图片描述
具体的各个生命周期处理的细节可以从详解java类的生命周期这篇博客中学习到,在这里主要分析的是连接初始化这两个阶段。

连接:分为验证,准备,解析三个部分,其中准备 完成为静态变量分配内存空间,所以在程序中为b,c两个个变量分配内存空间,并设置初始值,b为基本类型,所以默认值设为0,c也为基本类型,但是因为其声明为final对象(编译时javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将变量设置为指定的值),所以c设置为其指定值112。
初始化:该阶段开始执行类的构造,按照正常的类的初始化流程(文章头部提到),其整个流程执行过程如下:

Created with Raphaël 2.2.0 第1步;static StaticTest st = new StaticTest() 第2步;System.out.println("2"); 第3步;int a = 110; 第4步;System.out.println("3"); 第5步;System.out.println("a=" + a + ",b=" + b + ",c=" + c); 第6步;static int b = 111; 第7步;System.out.println("1"); 第8步;public static void main(String[] args) { staticFunction(); } 第9步; public static void staticFunction() { System.out.println("4"); }

首先按照从上向下的方式初始化静态变量,首先遇到的是st这个静态变量,new StaticTest(),所以开始执行类的构造,按照顺序首先从上到下先执行构造代码块,再执行成员变量的赋值,再执行构造函数,所以步骤2,3,4,5依次进行。当执行完st这个静态变量的初始化赋值后,接着向下执行其它静态成员变量的赋值所以步骤6执行。至此,所有静态成员变量初始化完毕,开始执行静态代码块的执行,所以步骤7执行。到了这步所有的静态变量,成员变量都已赋值,类也已经初始化构造完毕,开始执行成员方法,首先执行的是入口函数main,所以第8步执行,8调用静态方法,所以9执行------执行结束。

这就导致出现有趣的现象:“实例初始化竟然出现在静态初始化之前”。这里还需注意的就是a,b,c的初始化值问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值