Order of initialization of static variable in Java

2019-07-28 12:38发布

问题:

I have two classes in two different files, each one has a static variable, I would like to know if there is a way to predict which one will be initialized first (is it implementation dependant)? My code looks like this?

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

回答1:

It depends on when each class is first used.

From section 12.4.1 of the Java Language Specification:

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.

  • T is a class and a static method declared by T is invoked.

  • A static field declared by T is assigned.

  • A static field declared by T is used and the field is not a constant variable (§4.12.4).

  • T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

A reference to a static field (§8.3.1.1) causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

Section 12.4.2 of the JLS specifies the initialization procedure in detail.

To be honest, if your code requires one to be initialized before the other, despite having no obvious dependency, then you've got problems anyway.



回答2:

According to your example - there is no way to init B.b before A.a because the access of B class will invoke static initialization of its supper class first.

If you really need to do A logic before B - try to encapsulation it in static methods:

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


回答3:

JVM doesn't keep the record of all classes with it but when a class or the static member of class is requested, it loads the class from the memory. So the actual procedure that is followed is something like this:

When the class is requested very first time:

  1. All static Variables

  2. Static Blocks (by the order, first one first then second and so on)

  3. Instance Variables (Members)

  4. Initializer Blocks (by the order)

  5. Constructor

And the second or afterwards:

  1. All Instance Variables (Members)

  2. Initializer Blocks (by the Order)

  3. Constructor.

I hope this will help you.

Thanks...

Mr.777



标签: java static