前言
先声明一个常识,类域和局部变量初始化的差异如下,
局部变量不初始化会报错:
类中属性(也称域)不赋初值,默认为0,如果是引用默认为空。
正题
一、类中属性按照定义的顺序初始化
我们声明一个Child类,拥有两个构造方法:
我们在Main类中创建Child的两个对象:
输出结果:
结论:就算类中属性散乱定义在不同地方,初始化也会严格按照先后顺序执行。
二、属性的自初始化先于构造方法初始化
我们知道,构造方法的主要作用在于初始化类中的成员变量,那么它到底何时执行呢?
在这里,我们在构造函数里将child2引用指向了另一个对象:
输出结果如下:
我们看到,构造函数方法是后被调用的。
结论:构造函数的初始化晚于成员变量自初始化。
三、静态块和静态变量优先
静态方法又被称为类方法,静态属性被称为类域,总是最优先初始化。
静态方法初始化也有两种方法:
直接初始化
输出结果:采用静态块统一初始化
输出结果:
两种方法效果一样。但是,注意如果你静态块初始,你一定不能这么做:
这样做你是访问不了静态属性的。
你可以这么理解:静态块其实相当于一个属于静态属性的初始化函数,你就算在里面定义了变量,作用周期也括号范围内。所以,你的正确做法是:在外面定义好静态类型的引用而统一在静态块中初始化。
结论:一个类中初始化顺序是:静态->类属性->构造函数。
四、继承关系中的初始化顺序
我们增加一个Parent类:
然后让Child继承Paret类,并给Child增加一个静态块:
使用Main类调用Child:
结果:
我们可以看到:Parent和Child的静态块先被调用,之后按照先父类后子类的顺序进行了初始化,而且静态属性只初始化一次。
结论:拥有继承关系时,先是从父类到子类初始化静态属性,之后再是从父类到子类初始化非静态属性。
总结
- 单个类中初始化顺序:静态属性->非静态属性->构造函数
- 继承时初始化顺序:先从父类到子类初始化静态属性,再从父类到子类进行非静态初始工作。
- 静态属性都只初始化一次。