Java语言中,当实例化对象时对象所在类的所有成员变量首先要进行初始化。当所有类成员初始化后,才会调用对象所在类的构造函数创建对象。
(普通成员变量定义处默认初始化先与在构造函数中初始化)
Java程序初始化的三个原则:
1、静态对象(变量)优先于非静态对象(变量)进行初始化。其中静态对象(变量)只会初始化一次,非静态对象(变量可能会初始化很多次)
2、父类优先于子类进行初始化。
3、按照成员变量定义顺序进行初始化。哪怕变量定义散布在了方法定义之中,它们依然按照任意方法(包括了构造方法)被调用之前进行初始化。
1、静态初始化顺序优先于非静态
package com.demo001;
public class Demo1 {
static{
System.out.println("父类静态代码块");
}
public Demo1(){
System.out.println("父类构造方法");
}
{
System.out.println("父类非静态代码块");
}
public static void main(String[] args) {
new Demo1();
System.out.println("初始化顺序:静态代码块-->非静态代码块-->构造方法");
}
}
运行结果如下:
父类静态代码块
父类非静态代码块
父类构造方法
初始化顺序:静态代码块-->非静态代码块-->构造方法
2、父类优先于子类进行初始化
package com.demo001;
public class Demo2 extends Demo1{
static {
System.out.println("子类静态代码块");
}
{
System.out.println("子类非静态代码块");
}
public Demo2(){
System.out.println("子类构造方法");
}
public static void main(String[] args) {
new Demo2();
System.out.println("初始化顺序:父类静态代码块-->子类静态代码块-->父类非静态代码块-->父类构造方法-->子类非静态代码块-->子类构造方法");
}
}
运行结果如下:
父类静态代码块
子类静态代码块
父类非静态代码块
父类构造方法
子类非静态代码块
子类构造方法
初始化顺序:父类静态代码块-->子类静态代码块-->父类非静态代码块-->父类构造方法-->子类非静态代码块-->子类构造方法
注意:非静态(静态)成员域在定义时初始化和非静态块(静态)中初始化优先级是平级的,从上到下初始化,最后一次初始化为最终的值(不包括非静态的成员域在构造器中初始化)。
3、初始化平级情况
package com.demo001;
public class Demo3 {
static int a = 2;
static {
a=1;
}
static int b = 4;
static {
b=3;
}
public static void main(String[] args) {
System.out.println(a);
System.out.println(b);
}
}
运行结果如下:
1
3
总结:
初始化顺序:父类静态变量-->父类静态代码块-->子类静态变量-->子类静态代码块-->父类非静态变量-->父类非静态代码块-->父类构造方法-->子类非静态变量-->子类非静态代码块-->子类构造方法
知识来源: