0. 引言
一、代码块:
- 只有方法体,没有方法名、没有参数、没有返回
- 基本语法:
[修饰符] {方法体} - 静态代码块:修饰符为static,只能调用静态成员
- 普通代码块:无修饰符,可以调用类所有成员
二、构造方法:
- 方法名与类名相同,没有返回值,但不能写
void - 基本语法:`[修饰符] 类名(形参列表) {方法体}
1. 在同一个类中的调用顺序
A) 新建一个类取名PriorityTest,依次定义构造方法、普通代码块、静态代码块
class PriorityTest {
// 定义构造方法
public PriorityTest() {
System.out.println("构造方法被调用");
}
// 定义普通代码块
{
System.out.println("普通代码块被调用");
}
// 定义静态代码块
static {
System.out.println("静态代码块被调用");
}
}
B) 定义main方法,运行
public static void main(String[] args) {
PriorityTest priorityTest = new PriorityTest();
}
C) 执行结果
静态代码块被调用
普通代码块被调用
构造方法被调用
D) 分析原因
- 静态代码块随着类加载而执行,优先级最高
- 构造方法内最开始隐含了
super()和调用普通代码块:先执行super(),再调用普通代码块,最后执行构造方法
2. 在父子类中的调用顺序
前言:从上述分析可以看出,构造方法内部先执行super(),再调用普通代码块,最后执行构造方法。因此,如果存在父子类的继承关系,优先级顺序将更为复杂。下文将进一步分析父类与子类中静态代码块、普通代码块、构造方法的调用顺序。
A) 父类取名PriorityTestFather,依次定义构造方法、普通代码块、静态代码块
class PriorityTestFather {
// 定义构造方法
public PriorityTestFather() {
System.out.println("父类 构造方法被调用");
}
// 定义普通代码块
{
System.out.println("父类 普通代码块被调用");
}
// 定义静态代码块
static {
System.out.println("父类 静态代码块被调用");
}
}
B) 子类取名PriorityTestSon,依次定义构造方法、普通代码块、静态代码块
class PriorityTestSon extends PriorityTestFather {
// 定义构造方法
public PriorityTestSon() {
System.out.println("子类 构造方法被调用");
}
// 定义普通代码块
{
System.out.println("子类 普通代码块被调用");
}
// 定义静态代码块
static {
System.out.println("子类 静态代码块被调用");
}
}
C) 定义main方法,运行
public static void main(String[] args) {
PriorityTestSon priorityTestSon = new PriorityTestSon();
}
D) 执行结果
父类 静态代码块被调用
子类 静态代码块被调用
父类 普通代码块被调用
父类 构造方法被调用
子类 普通代码块被调用
子类 构造方法被调用
E) 分析原因
- 执行main方法,先加载父类.class进内存,后加载子类.class进内存,然后开始初始化对象。静态代码块随着类加载而执行,因此先后分别调用父类静态代码块、子类静态代码块。
- main方法初始化对象时,正如上文所述,构造方法内部会先执行super(),再调用普通代码块,最后执行构造方法。
- 第一步,执行子类的super(),运行父类构造方法。
- 第二步,父类构造方法内依旧按super()、普通代码块、构造方法的顺序依次执行。但是因为父类再往上super()就是Object类,所以没有打印内容。接下来,按父类普通代码块、父类构造方法的顺序依次执行。
- 第三步,执行子类的普通代码块
- 第四步,执行子类的构造方法
3. 总结
- 创建对象时,在一个类中的调用顺序
- ⑴调用静态代码块
- ⑵调用普通代码块
- ⑶调用构造方法
- 创建对象时,在父子类的调用顺序
- 静态代码块随类加载而执行;构造方法内先执行
super(),后调用普通代码块,最后执行构造方法 - ⑴父类静态代码块
- ⑵子类静态代码块
- ⑶父类普通代码块
- ⑷父类构造方法
- ⑸子类普通代码块
- ⑹子类构造方法
- 静态代码块随类加载而执行;构造方法内先执行
本文详细探讨了Java中静态代码块、普通代码块和构造方法的调用顺序。在同一个类中,静态代码块优先级最高,其次为普通代码块,最后是构造方法。在父子类中,父类的静态代码块先于子类的执行,接着是父类的构造方法(包括其内的super()、普通代码块),然后是子类的普通代码块,最后是子类的构造方法。

被折叠的 条评论
为什么被折叠?



