Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

According to the Java Language Specification (JLS), §12§12.4, "Initialization of Classes and Interfaces" [JLS 2005]:

...

Therefore, the presence of a static field triggers the initialization of a class. However, the initializer of a static field could depend on the initialization of another class, possibly creating an initialization cycle.

The JLS also states in §8§8.3.2.1, "Initializers for Class Variables" [JLS 2005]

...

This noncompliant code example contains an intra-class initialization cycle.

Code Block
bgColor#FFcccc

public class Cycle {
  private final int balance;
  private static final Cycle c = new Cycle();
  private static final int deposit = (int) (Math.random() * 100); // Random deposit

  public Cycle() {
    balance = deposit - 10; // Subtract processing fee
  }

  public static void main(String[] args) {
    System.out.println("The account balance is: " + c.balance);
  }
}

...

This compliant solution changes the initialization order of the class Cycle so that the fields are initialized without creating any dependency cycles. Specifically, the initialization of c is placed lexically after the initialization of deposit so that it occurs temporally after deposit is fully initialized.

Code Block
bgColor#ccccff

public class Cycle {
  private final int balance;
  private static final int deposit = (int) (Math.random() * 100); // Random deposit
  private static final Cycle c = new Cycle();  // Inserted after initialization of required fields
  public Cycle() {
    balance = deposit - 10; // Subtract processing fee
  }

  public static void main(String[] args) {
    System.out.println("The account balance is: " + c.balance);
  }
}

...

This noncompliant code example declares two classes with static variables whose values depend on each other. The cycle is obvious when the classes are seen together (as here) but is easy to miss when viewing the classes separately.

Code Block
bgColor#FFcccc

class A {
  public static final int a = B.b + 1;
  // ...
}

class B {
  public static final int b = A.a + 1;
  // ...
}

...

This compliant solution breaks the interclass cycle by eliminating one of the dependencies.

Code Block
bgColor#ccccff

class A {
  public static final int a = 2;
  // ...
}

// class B unchanged: b = A.a + 1

...

 

01. Declarations and Initialization (DCL)      01. Declarations and Initialization (DCL)