java静态代码块,构造方法,构造代码块的执行先后顺序

时间:2024-10-13 07:30:23

1、执行顺序

静态代码块>构造代码块>构造方法

原因:

  • 静态代码块(static{})在类加载的时候执行一次,是最早被执行的。
  • 构造代码块({}内的部分)在每一次创建对象时执行,始终在构造方法前执行。
  • 构造方法在新建对象时调用( 就是new的时候 )。

注意:

  • 静态代码块在类加载的时候就执行,所以它的优先级高于入口main()方法。
  • 当三种形式不止一次出现,同优先级是按照先后顺序执行。

程序代码示例:

public class StaticTest {
    public static StaticTest t1 = new StaticTest();
    public static StaticTest t2 = new StaticTest();

    {
        System.out.println("构造块");
    }

    static {
        System.out.println("静态块");
    }

    public static void main(String[] args) {
        StaticTest t = new StaticTest();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

执行main方法打印结果:
在这里插入图片描述


为什么会出现这种打印结果?

拓展知识点:静态域

静态域:分为静态变量,静态方法,静态块。当执行到静态域时,按照静态域的顺序加载。并且静态域只在类的第一次加载时执行

注意:加载了静态域的一部分,这时候不能再加载另一个静态域了,静态域必须当成一个整体来看待,否则加载会错乱。比如上面的代码,有静态变量和静态代码块儿,当加载了静态变量后,就不能加载静态代码块儿了

根据代码执行顺序:

(1)执行程序入口main方法时,首先加载类StaticTest
注意:加载类时并不会调用构造块和构造方法,只有静态域会执行
(2)加载类StaticTest,执行静态域的第一个静态变量StaticTest t1 = new StaticTest();,输出构造块和构造方法(空)。打印出构造块。
(3)由于每次new对象时,会执行一次构造块和构造方法,构造块总是在构造方法前执行,(当然,第一次new时,会先执行静态域,静态域〉构造块〉构造方法)所以执行StaticTest t1 = new StaticTest();时,执行了下面代码:

 	{
        System.out.println("构造块");
    }
  • 1
  • 2
  • 3

(4)同理,StaticTest t1 = new StaticTest();加载完后,以此执行第二个静态变量StaticTest t2 = new StaticTest();,执行构造块代码块。
(5)执行static静态块,完成对整个静态域的加载
(6)最后,再执行main方法,new StaticTest();,执行构造块。

附加:代码中添加了构造方法

public class StaticTest {
    public static StaticTest t1 = new StaticTest();
    public static StaticTest t2 = new StaticTest();

    {
        System.out.println("构造块");
    }

    static {
        System.out.println("静态块");
    }

    public StaticTest() {
        System.out.println("构造方法代码");
    }

    public static void main(String[] args) {
        StaticTest t = new StaticTest();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

执行main方法的打印结果:
在这里插入图片描述

总结:
1、每调用一次构造方法,则执行一次构造块
2、静态块只在类加载的时候加载一次
3、有多个静态变量或块时,按声明顺序加载


2、java中父类和子类代码执行顺序

父类和子类代码执行顺序:

父类静态代码块 =》 子类静态代码块 =》 父类代码块 =》 父类构造方法 =》 子类代码块 =》 子类构造方法


程序代码如下:
1、创建Father和Son类,让Son继承Father
2、编写Father和Son的代码

/**
 * 父类(抽象类)
 */
public abstract class Father {

    static {
        System.out.println("父类静态代码执行了");
    }

    {
        System.out.println("父类非静态代码执行了");
    }

    public Father() {
        System.out.println("父类构造函数代码执行了");
    }

    public static void main(String[] args) {
        Son son = new Son();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
/**
 * 子类(具体类)
 */
public class Son extends Father {

    static {
        System.out.println("子类静态代码执行了");
    }

    {
        System.out.println("子类非静态代码执行了");
    }

    public Son() {
        System.out.println("子类构造函数代码执行了");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

打印结果:
在这里插入图片描述

注意:由于代码的执行顺序不同,经常通过执行顺序进行后端初始化


拓展链接:
java的static关键字