本文实例使用的 Java 版本:

$ java -version
  openjdk version "11.0.8" 2020-07-14
  OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
  OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)
  

TL; DR

Java 类中的初始化顺序为:

父类静态变量 -> 父类静态代码块 -> 子类静态变量 -> 子类静态代码块 -> 父类变量 -> 父类代码块 -> 父类构造函数 -> 子类变量 -> 子类代码块 -> 子类构造函数 。

验证代码

父类:

package initOrder;

public class Parent {
    static String staticField = "parent static field";
    static {
        System.out.println(staticField);
        System.out.println("parent static code block");
    }

    String field = "parent field";
    {
        System.out.println(field);
        System.out.println("parent code block");
    }

    // constructor
    public Parent() {
        System.out.println("parent constructor");
    }

    // override function
    public void func() {
        System.out.println("parent function");
    }
}

子类:

package initOrder;

public class Child extends Parent {
    static String staticField = "child static field";
    static {
        System.out.println(staticField);
        System.out.println("child static code block");
    }

    String field = "child field";
    {
        System.out.println(field);
        System.out.println("child code block 1");
    }

    // constructor
    public Child() {
        System.out.println("child constructor");
    }

    // override function
    @Override
    public void func() {
        System.out.println("child function");
    }

    public static void main(String[] args) {
        System.out.println("child main function");
        new Child();
    }

    static {
        System.out.println("child static code block 2");
    }
}

若我们运行 Child 中的 main 函数,输出如下:

parent static field
parent static code block
child static field
child static code block
child static code block 2
child main function
parent field
parent code block
parent constructor
child field
child code block
child constructor

可见,Child 中的 main 函数,在静态块初始化之后,在类变量初始化之前。

我们在这两个类之外编写 main 函数,如下:

import initOrder.Child;

public class testInitOrder {
    public static void main(String[] args) {
        System.out.println("main function start");
        Child child = new Child();
        child.func();
        System.out.println("main function end");
    }
}

最后输出如下:

main function start
parent static field
parent static code block
child static field
child static code block
child static code block 2
parent field
parent code block
parent constructor
child field
child code block
child constructor
child function
main function end

可见,其遵循 静态变量、静态块、构造函数、变量、代码块 的初始化顺序。

Reference

  1. Java 类初始化顺序
    https://segmentfault.com/a/1190000004527951
    分享到:
分类: Java

发表评论

电子邮件地址不会被公开。 必填项已用*标注

验证码 *