1

我在两个不同的文件中有两个类,每个类都有一个静态变量,我想知道是否有一种方法可以预测哪个将首先初始化(它是否依赖于实现)?我的代码看起来像这样?

File1:
public class A
{
  public static boolean a = Logger.log();
}

File2:
public class B
{
  public static boolean b = Logger.log();
}

File3:
public class Logger
{
  public static boolean log();
}
4

3 回答 3

9

这取决于第一次使用每个类的时间。

Java 语言规范的第 12.4.1 节

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

  • T 是一个类,并创建了一个 T 的实例。

  • T 是一个类,并且调用了 T 声明的静态方法。

  • 分配了一个由 T 声明的静态字段。

  • 使用了由 T 声明的静态字段,并且该字段不是常量变量(第 4.12.4 节)。

  • T 是一个顶级类(第 7.6 节),并且执行在词法上嵌套在 T(第 8.1.3 节)中的断言语句(第 14.10 节)。

对静态字段(第 8.3.1.1 节)的引用导致仅对实际声明它的类或接口进行初始化,即使它可能通过子类、子接口或实现接口的类的名称来引用。

JLS 的第 12.4.2 节详细规定了初始化过程。

老实说,如果您的代码需要一个在另一个之前初始化,尽管没有明显的依赖关系,那么无论如何您都会遇到问题。

于 2013-02-18T12:34:53.690 回答
0

根据您的示例-无法在 Aa 之前初始化 Bb,因为 B 类的访问将首先调用其超级类的静态初始化。

如果您确实需要在 B 之前执行 A 逻辑 - 尝试将其封装在静态方法中:

public class A
{
  public static boolean a;
  public static init() {
   a = log();
  }
}

public class B
{
  public static boolean b;
  public static init() {
   b = log();
  }
}

public class Main
{
  public static void main(String[] args) {
   B.init();       
   A.init();      
  }
}
于 2013-02-18T12:43:12.167 回答
0

JVM 不会保存所有类的记录,但是当请求一个类或类的静态成员时,它会从内存中加载该类。所以遵循的实际过程是这样的:

当第一次要求上课时:

  1. 所有静态变量

  2. 静态块(按顺序,第一个在前,然后是第二个,依此类推)

  3. 实例变量(成员)

  4. 初始化块(按顺序)

  5. 构造函数

第二个或之后:

  1. 所有实例变量(成员)

  2. 初始化程序块(按顺序)

  3. 构造函数。

我希望这能帮到您。

谢谢...

777先生

于 2013-02-18T12:33:56.833 回答