public class Test {
public static int k = 0;
public static Test t1 = new Test("t1");
public static Test t2 = new Test("t2");
public static int i = print("i");
public static int n = 99;
private int a = 0;
public int j = print("j");
{
print("构造块");
}
static {
print("静态块");
}
public Test(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[]) {
Test t = new Test("init");
}
}
以上为试题,以下为分析
解析:
关键点一:在类的内部,变量定义的先后顺序决定了初始化的顺序。变量定义会在任何方法(包括构造器)被调用之前得到初始化。在所有的变量定义中,初始化的顺序是先静态对象,后非静态的对象。
关键点二:静态及非静态代码块都会在构造函数执行前执行,静态代码块只会在第一次调用类时执行一次,非静态代码块会在每次类调用时都执行。
步骤一:
Main中类被加载后,静态变量首先进行初始化,所有基本数据类型都设置为默认值:k,I,n=0;t1,t2-null
步骤二:
根据类中定义的顺序,所有静态变量执行初始化语句
当执行到public static Test t1 = new Test("t1");时,步骤二暂时入栈,某些静态变量的初始化过程被暂停,开始创建对象t1,进入步骤三
步骤三:
先初始化int a=0;j=null,之后分别给a,j赋值,之后执行非静态的代码块,之后构造方法被调用。之后是t2对象的创建,执行过程为同样的步骤。
输出结果为:
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
步骤四:
之后继续步骤二中的初始化步骤,为i赋值,将n赋值为99,执行静态代码块
i赋值的输出结果为:
7:i i=6 n=6
静态代码块的输出为:
8:静态块 i=7 n=99
注意此时n才被赋值为99
步骤五:
进入t对象的构造过程,步骤同t1,t2
输出为:
9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102