JAVA类的初始化过程

fudan
java中一个类初始化的过程

自动初始化

java类中的字段,第一步是自动初始化,比如定义了

1
private int i;

由于没有给其赋值,i会被自动赋值为0。这个步骤是仅限于类中的字段的,如果方法中的临时变量,不会有这个动作。而且如果在方法中使用未经赋值的变量,编译会不通过

指定初始化

第二步是指定初始化

1
private int i = 3;

如果有了显式的赋初值,那么第一步的自动初始化就不会发生了。但是该步骤和自动初始化,必定发生其一。即使在构造方法里给i赋值为4,还是首先会调用指定初始化,先赋值成3再赋值成4

初始化语句块

第三步是初始化语句块初始化

1
2
3
{
i = 4;
}

这个动作发生在自动初始化或者指定初始化之后,发生在构造方法初始化之前。如果没有初始化语句块,那么这个步骤就不会发生

构造方法初始化

第四步才是构造方法中的初始化

1
2
3
public className(){
i = 4;
}

这个动作是发生在初始化语句块之后,如果没有的话,就是发生在自动初始化或者指定初始化之后。这个动作也是初始化的最后一个步骤。在类中的任何方法执行之前(包括构造方法),首先会完成所有字段的初始化

类只在初次使用时才会被加载

“初次使用”通常是指创建类的第一个对象时,或者当初次访问类中的static字段或者static方法时

构造方法实际上也是static方法(只是static关键字没有要求显式地写出来),所以也可以说,类的加载是发生在类的任何static成员(包括static字段、static方法、构造方法)被初次访问时

static优先

当初始化类的字段时,会先初始化static字段,再初始化非static字段

继承关系

在调用构造方法时,会从最顶端的基类开始,依次调用每个类的构造方法。如果基类的构造方法是默认构造方法(不含构造方法参数),那么就不需要显式地调用super(),但是如果基类只定义了含参数的构造方法,就必须显式地调用super()