名词解释
静态代码块:类中以*static {}*形式包围起来的代码块,Jvm加载类时执行,仅执行一次。
构造代码块:类中以*{}*形式包围起来的代码块,不包括方法中的普通代码块。每次创建对象时都要执行。
构造函数:每次创建对象时就会执行构造函数,构造函数的作用时给对象初始化。
单个类中的执行顺序
执行顺序
静态代码块 > 构造代码块 > 构造函数
验证
执行以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class HelloTest { public HelloTest() { System.out.println("执行 HelloTest() 构造函数"); } { System.out.println("执行构造代码块"); } static { System.out.println("执行静态代码块"); } public static void main(String[] args) { System.out.println("准备new第一个对象"); HelloTest one = new HelloTest(); System.out.println("准备new第二个对象"); HelloTest two = new HelloTest(); } }
|
结果输出:
1 2 3 4 5 6 7
| 准备new第一个对象 执行静态代码块 执行构造代码块 执行 HelloTest() 构造函数 准备new第二个对象 执行构造代码块 执行 HelloTest() 构造函数
|
继承关系下的执行顺序
考虑父子继承情况,顺序又会是怎么样呢?
执行顺序
父类静态代码块 > 子类静态代码块 > 父类构造代码块 > 父类构造函数 > 子类构造代码块 > 子类构造函数
验证
执行以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public static class HelloA { public HelloA() { System.out.println("执行HelloA的构造函数"); }
{ System.out.println("执行HelloA的构造代码块"); }
static { System.out.println("执行HelloA的静态代码块"); } }
public static class HelloB extends HelloA { public HelloB() { System.out.println("执行HelloB的构造函数"); }
{ System.out.println("执行HelloB的构造代码块"); }
static { System.out.println("执行HelloB的静态代码块"); } public static void main(String[] args) { HelloB b = new HelloB(); } }
|
执行结果如下:
1 2 3 4 5 6
| 执行HelloA的静态代码块 执行HelloB的静态代码块 执行HelloA的构造代码块 执行HelloA的构造函数 执行HelloB的构造代码块 执行HelloB的构造函数
|