Java静态final字段初始化顺序 [英] Java static final field initialization order
问题描述
我试图理解初始化顺序的行为,当静态字段使用对同一封闭类对象的引用初始化时。
public class Test {
static final Test t = new Test();
static int a = 5;
Test(){
System.out.println(a =+ a);
}
public static void main(String [] args){
new Test();
}
}
上述代码段的输出:
a = 0
a = 5
如果我修改变量 a
为除了 static
:
static final a = 5;
a = 5;
final a = 5;
输出为:
a = 5
a = 5
请注意,输出为 a = 5& a = 5
,即使 t& a
声明为
static final
,在这种情况下 t
$ c> a
static final成员在其他静态成员之前初始化。
非最终静态成员按照出现顺序初始化
因此,在第一种情况下:
static Test t = new Test();
static int a = 5;
在 a
之前首先调用构造函数初始化,因此显示 a = 0
。
在 t
之前初始化一个,因此当第一个实例时显示 a = 5
创建测试
。当 a
不是静态的,它在执行构造函数之前被初始化,因此再次显示 a = 5
查看 docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2rel =nofollow> JLS 的12.4.2:
$然后,初始化接口的最终类变量和字段,这些接口的值为编译时常量[] <$> <$> <$> <$><表达式(§8.3.2.1,§9.3.1,§13.4.9,§15.28)。
...
- 接下来,按文本顺序执行类的类变量初始化器和静态初始化器,或接口的字段初始化器,就好像它们是单个块。
您会看到最终的类变量(即static final)变量(如果值是编译时间)常量表达式。 5
是一个常量表达式。 new Test()
不是。因此, a 在
t
之前初始化,即使两者都是静态final。
I tried to understand the behavior of initialization order when static fields are initialized with a reference to the same enclosing class object.
public class Test {
static final Test t=new Test();
static int a=5;
Test(){
System.out.println("a="+a);
}
public static void main(String[] args) {
new Test();
}
}
Output of above piece of code is:
a=0
a=5
If I modify variable a
to anything else other than plain static
:
static final a=5;
a=5;
final a=5;
The output is:
a=5
a=5
Why is this behavior?
Note that the output is a=5 & a=5
even when both t & a
are declared as static final
in which case t
precedes the declaration of a
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.
这篇关于Java静态final字段初始化顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!