看过Thinking in java的人都知道,在不考虑父类的情况下,类的
初始化顺序相对简单,总体是先静态的,然后是非静态的。这里都包括成员变量和代码块。对于静态变量和静态代码块,不管它们在
何处定义,总是按照其先后顺序进行初始化。同理,非静态变量和非静态代码块也是如此。
下面上热菜:
class="java">
public class Test1 {
public static int k = 0;
public static Test1 initOrder1 = new Test1("t1");
public static Test1 initOrder2 = new Test1("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("构造块");
}
static {
print("静态块");
}
public Test1(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
++n;
}
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
}
public static void main(String[] args) {
Test1 initOrder = new Test1("init");
}
}
什么!!!居然还有这样的的:
public static Test1 initOrder1 = new Test1("t1");
对我这种小白来说,这太不能
理解了。伤脑细胞!
我们先看看答案吧:
1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:静态块 i=7 n=99
9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102
按照惯例,程序进入main()方法后,在调用new Test1()的一瞬间,Test1开始初始化了,k=0。当进行到public static Test1 initOrder1 = new Test1("t1");的时候,就要开始实例化了,所以接下来的静态变量都先等着,等排在前面的initOrder1先办完事了,才有你们这群小屁孩的事。因为静态变量属于类,而非类的实例,所以我initOrder1只好先对
实例变量和非静态代码块下手了(小鲜肉,我来了。。。)。所以就会执行如下语句:
public int j = print("j");
{
print("构造块");
}
得到输出:
1:j i=0 n=0
2:构造块 i=1 n=1
然后再调用
构造器,就可以完成对initOrder1的初始化,顺便打印出了
3:t1 i=2 n=2
接下来该初始化initOrder2了,原理同上。打印出:
4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
然后继续其他成员的初始化。注意,当初始化到了
public static int n = 99;
就会初始化静态代码块哟,要注意哈。别以为是顺序下来的。当初始化全部完成后,然后调用Test1("init"),至此,完成了mian()方法中的
变量初始化。大功告成。
如果有什么讲错的,欢迎各位看官批评指正。