【问题标题】:Execution sequence of static, constructor and blocks in java [duplicate]java中静态,构造函数和块的执行顺序[重复]
【发布时间】:2020-04-28 04:20:39
【问题描述】:

这是一个面试问题,手动编写以下代码的输出:

public class StaticTest {

    public static int k = 0;
    public static StaticTest t1 = new StaticTest("t1");
    public static StaticTest t2 = new StaticTest("t2");
    public static int i = print("i");
    public static int n = 99;
    public int j = print("j");

    {
        print("Constructor Block");
    }

    static {
        print("Static Block");
    }

    public StaticTest(String str) {
        System.out.println((++k)+":"+str+" i="+i+" n="+n);
        ++n;
        ++i;
    }
    public static int print(String str) {
        System.out.println((++k)+":"+str+" i="+i+" n="+n);
        ++i;
        return ++n;
    }

    public static void main(String[] args) {
        StaticTest t = new StaticTest("init");
    }

}

输出:

1:j i=0 n=0
2:Constructor Block i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:Constructor Block i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:Static Block i=7 n=99
9:j i=8 n=100
10:Constructor Block i=9 n=101
11:init i=10 n=102

很困惑为什么要先执行print,甚至以j开头? 我认为静态字段和块是在类加载时执行的,所以至少它应该在public int j = print("j");之前执行public static int i = print("i");

【问题讨论】:

标签: java constructor static


【解决方案1】:

JVM 在加载类时在 main 方法之前执行 静态块。 当类被加载时,静态块只会执行一次。但是 Instance Initialization blocksConstructor 将在每次创建 Class 的对象时运行。

静态初始化块是静态的,因此它们属于特定类而不属于类的实例。实例初始化块不属于类,它们是每次创建类的新实例时执行。

当我们执行上面的类时,StaticTest 类被加载到 JVM 中。

它做的第一件事是,在 main() 方法被执行之前执行所有静态块。因此,你的输出的前 8 行将在你的 main 方法被触发之前执行。

按照存在的顺序,public static StaticTest t1 = new StaticTest("t1")会在public static int k = 0之后执行。

由于有新的实例初始化,

  • 第一行表示public int j = print("j")的执行
  • 第2行表示print("Constructor Block")的执行
  • 第3行表示创建对象时构造函数StaticTest("t1")的执行。

实例初始化块在类被初始化和构造函数被调用之前执行。因此print("Constructor Block") 在构造函数之前执行。而print("j") 优先于一切。

像上面的场景public static StaticTest t2 = new StaticTest("t2") 也遵循相同的执行流程,对应于第 4,5 和 6 行。 然后public static int i = print("i")对应Line和8。

  • 第9行表示public int j = print("j")的执行
  • 第10行表示print("Constructor Block")的执行
  • 第11行表示创建对象时构造函数StaticTest("init")的执行。

【讨论】:

  • '实例初始化块在类被初始化时执行':否。类被初始化一次。实例初始化块在构造实例时执行,而不是“在构造函数之前”,而是在构造函数调用期间调用super()之后。
猜你喜欢
  • 2021-09-09
  • 2012-07-31
  • 1970-01-01
  • 2022-12-22
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多