According to the The Java Language Specification (JLS), §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.
...
This statement does not apply to instances that use values of static final fields that are initialized at a later stage. Declaring a field to be static final is insufficient to guarantee that it is fully initialized before being read.
...
This noncompliant code example contains an intraclass 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 breaks the interclass cycle by eliminating the dependency of A
on B
.:
Code Block | ||
---|---|---|
| ||
class A { public static final int a = 2; // ... } class B { public static final int b = A.a + 1; // ... } |
...
This code correctly initializes A.a
to 1, using the Oracle JVM, regardless of whether A
or B
is loaded first. However, the JLS does not guarantee that A.a
to be properly initialized. Furthermore, the initialization cycle makes this system harder to maintain and more likely to break in surprising ways when modified.
...
Initialization cycles may lead to unexpected results.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
DCL00-J | Low | Unlikely | Medium | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
CodeSonar |
| JAVA.STRUCT.UA JAVA.STRUCT.UA.DEFAULT | Useless Assignment (Java) Useless Assignment to Default (Java) | ||||||
Parasoft Jtest |
| CERT.DCL00.ACD | Ensure that files do not contain cyclical dependencies | ||||||
PVS-Studio |
| V6050 | |||||||
SonarQube |
| Classes should not access their own subclasses during initialization |
Related Guidelines
VOID DCL14-CPP. Avoid assumptions about the initialization order between translation units | |
Initialization of Variables [LAV] | |
CWE-665, Improper Initialization |
Bibliography
Puzzle 49, "Larger than Life" | |
[JLS 2005] | §8.3.2.1, "Initializers for Class Variables" §12.4, "Initialization of Classes and Interfaces |
" | |
[Seacord 2015] | DCL00-J. Prevent class initialization cycles LiveLesson |
...
...