<init>
与<clinit>
<init>
Java在编译之后会在字节码文件中生成<init>
方法,称之为实例构造器,该实例构造器会将语句块,变量初始化,调用父类的构造器等操作收敛到<init>
方法中,收敛顺序(这里只讨论非静态变量和语句块)为:
1. 父类变量初始化
2. 父类语句块
3. 父类构造函数
4. 子类变量初始化
5. 子类语句块
6. 子类构造函数
所谓收敛到<init>
方法中的意思就是,将这些操作放入到<init>
中去执行
<clinit>
Java在编译之后会在字节码文件中生成<clinit>
方法,称之为类构造器,类构造器同实例构造器一样,也会将静态语句块,静态变量初始化,收敛到<clinit>
方法中,收敛顺序为:
1. 父类静态变量初始化
2. 父类静态语句块
3. 子类静态变量初始化
4. 子类静态语句块
<clinit>
方法是在类加载过程中执行的,而<init>
是在对象实例化执行的,所以<clinit>
一定比<init>
先执行。所以整个顺序就是:
1. 父类静态变量初始化
2. 父类静态语句块
3. 子类静态变量初始化
4. 子类静态语句块
5. 父类变量初始化
6. 父类语句块
7. 父类构造函数
8. 子类变量初始化
9. 子类语句块
10. 子类构造函数
初始化顺序
如下父类代码
public class Parent {
static int a = 1;
int b = 1;
static {
System.out.println("parent static block(a):" + (++a));
}
{
System.out.println("parent block(b):" + (++b));
}
public Parent() {
System.out.println("parent construction");
}
}
子类代码
public class Child extends Parent {
static int a = 1;
int b = 1;
static {
System.out.println("child static block(a):" + (++a));
}
{
System.out.println("child block(b):" + (++b));
}
public Child() {
System.out.println("child construction");
}
public static void main(String[] args) {
new Child();
}
}
最终输出结果为
parent static block(a):2
child static block(a):2
parent block(b):2
parent construction
child block(b):2
child construction