Wiki Markup |
---|
According to the _Java Language Specification_ (JLS), [§12§12.4, "Initialization of Classes and Interfaces" |http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.4] \[[JLS 2005|AA. References#JLS 05]\]: |
Initialization of a class consists of executing its
static
initializers and the initializers forstatic
fields (class variables) declared in the class.
Wiki Markup |
---|
In other wordsTherefore, the presence of a {{static}} field triggerscan trigger the initialization of a class. However, 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" |http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.2.1] \[[JLS 2005|AA. References#JLS 05]\] |
...
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); } } |
The Cycle
class declares a private static final
class variable which is initialized to a new instance of the Cycle
class. Static initializers are guaranteed to be invoked once before the first use of a static class member or the first invocation of a constructor.
...
Wiki Markup |
---|
The JLS permits implementations to ignore the possibility of such recursive initialization cycles \[[Bloch 2005|AA. References#Bloch 05]\]. |
Compliant Solution (Intra-class Cycle)
...
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);
}
}
|
Such initialization cycles become insidious when many fields are involved. Consequently, it is important to ensure that the control flow lacks such cycles.
...
DCL14-CPP. Avoid assumptions about the initialization order between translation units | ||||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="625388889fd883b3-0cd9b235-432d44ce-bbb0b6e1-4fe86f99889392ed09ea6ab9"><ac:plain-text-body><![CDATA[ | [ISO/IEC TR 24772:2010 | http://www.aitcnet.org/isai/] | Initialization of variables [LAV] | ]]></ac:plain-text-body></ac:structured-macro> |
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="3ee4228867e86a07-7e3a0937-4785473b-8f7aaf07-940b1b884d53117e94ee0c4f"><ac:plain-text-body><![CDATA[ | [[JLS 2005 | AA. References#JLS 05]] | [§8§8.3.2.1, Initializers for Class Variables | http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.2.1] | ]]></ac:plain-text-body></ac:structured-macro> |
| |||||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="642dde58243639ac-ac9103db-40ec486a-95529767-b98b46b41cb374b33c2a6d56"><ac:plain-text-body><![CDATA[ | [[Bloch 2005 | AA. References#Bloch 05]] | Puzzle 49. Larger than life | ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="f536c3325714ea90-c94b3b0f-45804ee8-a0109408-7388c372b495df9ddc8576ef"><ac:plain-text-body><![CDATA[ | [[MITRE 2009 | AA. References#MITRE 09]] | [CWE-665 | http://cwe.mitre.org/data/definitions/665.html]. Improper initialization | ]]></ac:plain-text-body></ac:structured-macro> |
...