6

嗨stackoverflow成员,这是一个与“类加载时间”的实际含义相关的小问题。

例如下面的代码:

public class Sequence {
    Sequence() {
        System.out.print("c ");
    }
    {
        System.out.print("y ");
    }
    public static void main(String[] args) {
        System.out.println("Indeed");
        new Sequence().go();
    }
    void go() {
        System.out.print("g ");
    }
    static { System.out.println("x "); }
} 

它确实打印出第一个静态的“x”,因此静态初始化块总是在“类加载时间”加载。我明白了,但你知道这个加载时间是什么时候发生的吗?我想当类第一次通过创建第一个对象在主方法中被调用时,但在这种情况下,通过打印出第一个“确实”,结果应该是不同的。任何人都可以帮助我澄清这个疑问?我已经检查了其他关于这个论点的帖子,但我仍然认为(至少对我而言)更清楚地知道在上面报告的代码中,“类加载时间”何时发生。

提前致谢。

4

5 回答 5

3

由于您的main方法位于classSequence,因此需要首先由 JVM 加载。"x"因此,首先要打印出来是完全有道理的。

于 2013-02-06T11:29:21.110 回答
3

你是对的,静态块是run在加载类时。当您运行程序时,这会发生在您的情况下。因为 main 方法本身在类内部,所以之前Sequence的输出是正确的。xIndeed

于 2013-02-06T11:29:50.500 回答
3

您的问题的答案在JLS 第 12.4.1 章初始化发生时

类或接口类型T将在以下任何一项第一次出现之前立即初始化:

  • T是一个类,并T创建了一个实例。
  • T是一个类,并T调用由声明的静态方法。
  • T分配了由声明的静态字段。
  • 使用声明的静态字段,T并且该字段不是常量变量(第 4.12.4 节)。
  • T是一个顶级类(第 7.6 节),并且T执行在词法上嵌套在(第 8.1.3 节)中的断言语句(第 14.10 节)。

我建议您从JLS 第 12.4 章开始阅读以上几行内容。类和接口的初始化

从第 12 章开始。 Execution,它准确地描述了何时需要加载一个类。初始化将在加载后完成。

于 2013-02-06T11:33:41.977 回答
3

静态初始化块在类加载时执行是不正确的。它们在类初始化时执行。前者发生的确切时间点是未指定的,而对后者有严格的规范:它发生在类的第一次运行时访问时。

于 2013-02-06T11:34:40.927 回答
1

Sequence必须在 JVM 调用该方法之前加载该类main,这会导致发生静态初始化,因此为什么x要首先打印出来。

于 2013-02-06T11:31:56.170 回答