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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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)