static final members are initialized before other static members.
non final static members are initialized in order of appearance
Therefore, in your first case :
static Test t=new Test();
static int a=5;
The constructor is first called before a
is initialized, so a=0
is displayed.
In the second case, static final a
is initialized before t
, so a=5
is displayed when the first instance of Test
is created. When a
is not static, it is initialized prior to the execution of the constructor, so again a=5
is displayed.
Regarding the edit in your question.
Looking at section 12.4.2 of the JLS :
- Then, initialize the final class variables and fields of interfaces whose values are compile-time constant expressions (§8.3.2.1, §9.3.1, §13.4.9, §15.28).
...
- Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.
You see that final class variables (i.e. static final) are initialized before the rest of the static variables only if their values are compile time constant expressions. 5
is a constant expression. new Test()
is not. Therefore a
is initialized before t
even if both are static final.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…