Java中静态变量的初始化顺序

时间:2013-02-18 12:26:37

标签: java static

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

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();
}

3 个答案:

答案 0 :(得分:8)

这取决于每个班级首次使用

来自section 12.4.1 of the Java Language Specification

  

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

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

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

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

  •   
  • 使用T声明的静态字段,该字段不是常量变量(§4.12.4)。

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

  •   
     

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

JLS的

Section 12.4.2详细指定了初始化过程。

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

答案 1 :(得分:0)

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

第一次要求上课时:

  1. 所有静态变量

  2. 静态区块(按顺序排列,先是第一个,然后是第二个,依此类推)

  3. 实例变量(成员)

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

  5. 构造

  6. 第二次或之后:

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

    2. 初始化程序块(按订单)

    3. 构造

    4. 我希望这会对你有所帮助。

      ...谢谢

      Mr.777

答案 2 :(得分:0)

根据你的例子 - 在A.a之前无法初始化B.b,因为B类的访问将首先调用其supper类的静态初始化。

如果你真的需要在B之前做一个逻辑 - 尝试将它封装在静态方法中:

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();      
  }
}