Java中代码块的执行顺序
今天我给大家分享一下关于Java中代码块的执行顺序的理解,大家应该都在其他地方看到了这样的结论:
静态代码块,构造代码块,构造方法的执行顺序:
- 静态代码块 > 构造代码块 >构造方法(构造代码块可自行去试验)
- 静态代码块会随着类的加载而加载,会被优先执行
- 子类的初始化之前先进行父类的初始化
这个结论到底怎么去理解,我通过一个实例给大家详细讲解下,让大家彻底明白他们的执行顺序到底是怎样的:
这个例子是我之前看过的一个面试题,我稍微改动了下,请问输出的结果是:
**class X**{
static {
System.out.println("zheshi x");
}
Y b=new Y();
X(){
System.out.println("X");
}
}
**class Y**{
Y(){
System.out.println("Y");
}
}
public **class Z** extends **X**{
static {
System.out.println("zheshi z");
}
Y y=new Y();
Z(){
System.out.println("Z");
}
public static void main(String[] args) {
new Z();
}
}
首先,要知道,java虚拟机运行时,首先调用main() 方法;
所以第一步,class Z就先加载到了内存中;
而class Z 继承class X,所以class X也加载到了内存中;
静态代码块的加载
- 静态代码块随着类的加载而加载,而加载的顺序,是父类先加载,然后子类在加载。
所以此时,class X的中静态方法先执行,之后class Z中的静态方法执行;所以输出的头两行内容为:
zheshi x
zheshi z
类的初始化
类的初始化是随着对象的创建而开始的;这里需要注意的是类被加载到内存中,并不等于就创建对象了,成员变量的初始化分为三个步骤,分别是:
- 默认初始化
- 显示初始化
- 构造方法初始化
怎么理解这三者呢?往下看
假设有一个类Student:
class Student{
int age=18;
Student(){
age =20;
}
}
对于成员变量age:
默认初始化:值为0,
显示初始化:值为18
构造方法初始化:值为20;
所以最终结果为20
所以接下来,看有没有对象的创建,main方法开始执行,执行到了new Z(),此时,class Z的对象就创建了,所以成员变量就开始了上述的初始化过程,但是,这时,大家又要注意了,初始化的过程也是先让父类进行初始化,然后子类在进行初始化,所以class X先进行初始化,执行到: Y b=new Y(); class Y对象又创建了,所以进行class Y初始化,所以输出中第三行结果为:
Y
接下来回到class X的构造方法,输出中的第四行为:
X
最后回到了class Z中构造方法,输出:
Z
所以整个结果输出为:
**zheshi x
zheshi z
Y
X
Y
Z
**
<关于类及其父类的加载,具体可以查阅jvm虚拟机,搜索双亲委派机制>