Java 将首先将静态变量初始化为默认值(null、0 和等效值)。无论是否指定了初始值,都会执行此操作。
然后它将运行从类的开头到底部的所有静态代码块(不是静态方法!)。初始化也被认为是代码块,它按照文件中指定的顺序运行。因此,这样的代码:
// static block of code in front
static Type variable = initialValue;
// static block of code in-between
static OtherType anotherVariable = someInitialValue;
// static block of code below
大致相当于(大致 - 因为它们在语法上不等价)
static Type variable;
static OtherType anotherVariable;
// static block of code in front
static {
variable = initialValue;
}
// static block of code in-between
static {
anotherVariable = someInitialValue;
}
// static block of code below
(就在对构造函数的任何调用之前,所有非静态代码块都将在调用构造函数之前运行。不过,它与 OP 的代码段不是很相关。)
从上面的方案中,Foo()
将调用构造函数。并且将被初始化为 1 count1
。count2
执行完singleton = new Foo()
初始化器后,会继续执行初始化count2 = 0
,并有效设置count2
为0。
此时,我们将进入main()
函数,并打印出来。如果构造函数被第二次调用,如上所述,非静态代码块将在构造函数之前运行,然后再次调用构造函数以将 和 的值加count1
1。count2
这一步没有什么奇怪的事情发生。
可以尝试编译运行这段代码看看效果:
class Foo {
static {
System.out.println("static 0: " + Foo.sigleton + " " + Foo.sigleton.count1 + " " + Foo.sigleton.count2);
}
private static Foo sigleton=new Foo();
static {
System.out.println("static 1: " + sigleton + " " + sigleton.count1 + " " + sigleton.count2);
}
private static int count1;
static {
System.out.println("static 2: " + sigleton + " " + sigleton.count1 + " " + sigleton.count2);
}
private static int count2=0;
static {
System.out.println("static 3: " + sigleton + " " + count1 + " " + count2);
}
{
System.out.println("non-static 1: " + sigleton + " " + count1 + " " + count2);
}
private Foo (){
count1++;
count2++;
System.out.println(count1 + " " + count2);
}
{
System.out.println("non-static 2: " + sigleton + " " + count1 + " " + count2);
}
public static Foo getInstance(){
return sigleton;
}
public static void main(String[] args) {
Foo f= Foo.getInstance(); // case 1
System.out.println(f.count1);
System.out.println(f.count2);
Foo t= new Foo(); // case 2
System.out.println(t.count1);
System.out.println(t.count2);
}
}