3

Java · 类的初始化顺序

 2 years ago
source link: https://blog.triplez.cn/posts/java-class-initialization/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文实例使用的 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

知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK