扩展资料:
https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.6
给喜欢看官方文档的深入学习者
初始化顺序原则
- 静态成员变量、静态构造块(也有称静态代码块),会随着类的加载而执行,因此在类的生命周期内,只会执行一次;
- 非静态的(成员变量、构造块、构造方法)是随着对象的初始化而执行的,因为每构造一个对象,都会执行一次。
- 同是静态/非静态,按照代码声明顺序来执行,构造方法最后执行。
速记
- 父类先于子类
- 静态 -> 非静态 -> 构造方法
- 同优先级按代码顺序执行
例子
public class Main {
public static void main(String[] args) {
new C();
}
}
class A {
static {
System.out.println("A: static initializer block");
}
{
System.out.println("A: non static initializer block");
}
public A() {
System.out.println("A: constructor");
}
}
class B extends A {
static {
System.out.println("B: static initializer block");
}
private static A clazz = new A();
{
System.out.println("B: non static initializer block");
}
public B() {
System.out.println("B: constructor");
}
}
class C extends B {
private static A clazz = new A();
static {
System.out.println("C: static initializer block");
}
{
System.out.println("C: non static initializer block");
}
public C() {
System.out.println("C: constructor");
}
}
输出及解释
// A静态构造开始
A: static initializer block
// A静态构造结束
// B静态构造开始
B: static initializer block // B的静态构造块比静态成员变量声明早,因此先执行静态构造块,再加载静态成员变量
A: non static initializer block // 因为A的静态构造块已经加载过一次,因此不再加载
A: constructor
// B静态构造结束
// C静态构造开始
A: non static initializer block // C的静态成员变量比静态构造块声明早,因此先加载静态成员变量
A: constructor
C: static initializer block
// C静态构造结束
// 以上为static的相关构造,以下为非static的构造
A: non static initializer block
A: constructor
B: non static initializer block
B: constructor
C: non static initializer block
C: constructor
相关题目
https://www.nowcoder.com/questionTerminal/df71c590125948c8a1d6f8775b41ece1
https://www.nowcoder.com/questionTerminal/b15b6a4450814167b8cc2b84392f6c2f
https://www.nowcoder.com/questionTerminal/aae05fb690d54b5a90fa9af09307addc