如果不考虑父类的话,简单来说是先进行静态初始化,后进行非静态初始化。
静态初始化包括静态成员变量的初始化和静态块,实际上编译时都会集中到static块中。
而非静态初始化包括非静态成员变量初始化和非静态块以及构造方法,编译后都会集中到构造方法中。
如果没有相互调用那么很简单,先进行静态初始化,如果静态初始化过程中又调用后者呢?
可以写一个代码试验一下:
public class Main {
public static void main(String[] args) {
new Main();
}
static {
System.out.println("1");
new Main();
System.out.println("2");
new Main();
System.out.println("3");
}
public Main() {
System.out.println("Main()");
}
}
输出:
1
Main()
2
Main()
3
Main()
可以看到确实是先进行静态初始化,可是中间夹杂着对于构造方法的调用。
虽然编译器没有报错,但是这种调用其实是有风险的。
因为静态成员变量(假设有的话)并未初始化的过程中就调用类的构造函数,假设有依赖的情况下,实际上过程是不可控的。
看下面这个例子:
public class Main {
public static void main(String[] args) {
new Main(1);
}
private static String prefix;
static {
new Main(2);
prefix = "Main";
}
public Main(int id) {
System.out.println(prefix + "-" + id);
}
}
能想象到这种输出吗?
null-2
Main-1
所以如果非要在静态初始化过程中,调用本类的构造函数。
一定要注意初始化顺序问题,精确到语句。