应用实例:
public class Test1 {
public static int k = 0;
public static Test1 t1 = new Test1("t1");
public static Test1 t2 = 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.print("Test1:");
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++i;++n;
}
public static int print(String str){
System.out.print("print:");
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
public static void main(String[] args) {
Test1 t = new Test1("init");
}
}
运行结果:
解析:
首先对所有数据域初始化:k , i , n , j被初始化为0。
从上倒下按照类声明出现的次序,依次执行。静态域要比非静态域先执行。
如果静态域中有对非静态域的调用,此时调用的是非静态域变量的初始化值。
在本例中 先执行第一行。
public static int k = 0;//k=0
执行第二行:
public static Test1 t1 = new Test1("t1");
调用构造函数实例化t1对象,每次实例化对象都会执行非静态域中的语句;所以先执行代码
public int j = print("j");
找到print方法,并传参,执行结果为
print: 1:j: i=0 n=0
接着执行对象初始化块即:
{
print("构造块");
}
结果为:
print:2:构造块 i=1 n=1
继续向下执行,传参数t1到Test1构造方法,结果为:
Test1:3:t1 i=2 n=2
到此public static Test1 t1 = new Test1("t1");
这句代码执行完毕。
继续向下执行public static Test1 t2 = new Test1("t2");
与前文类似会输出以下三条语句:
print:4:j i=3 n=3
print:5:构造块 i=4 n=4
Test1:6:t2 i=5 n=5
之后继续向下执行public static int i = print("i");
执行结果:
print:7:i i=6 n=6
然后给n赋值为99,执行static{ print("静态块"); }
print:8:静态块 i=7 n=99
此时,所有的静态域都被初始化完毕,此时开始执行main方法中的Test1 t = new Test1("init");
与前文类似,此条语句会输出
print:9:j i=8 n=100
print:10:构造块 i=9 n=101
Test1:11:init i=10 n=102
综上,输出结果为
print:1:j i=0 n=0
print:2:构造块 i=1 n=1
Test1:3:t1 i=2 n=2
print:4:j i=3 n=3
print:5:构造块 i=4 n=4
Test1:6:t2 i=5 n=5
print:7:i i=6 n=6
print:8:静态块 i=7 n=99
print:9:j i=8 n=100
print:10:构造块 i=9 n=101
Test1:11:init i=10 n=102
总结:
首先初始化静态块,如果构造器调用了非静态变量,按变量的初始值处理.(int型初始化为0, boolean初始化为false, 对象初始化为null)
直至所有静态化块都初始完毕,再执行main函数中的方法。
与静态初始化块对应的是对象初始化块,对象初始化块是根据创建的对象来执行的。每new一个新对象都会从上到下执行对象初始化块中的语句。