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");
}
} 输出结果:
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
解析:
1.若没有main函数中的代码,结果1-8仍可输出,因为这是在程序编译时就执行的
2.对于类中的各代码的执行顺序:静态变量在类编译时全部初始化,非静态变量仅在实例化时才初始化
所以先初始化t1,newTest1()时会将类中非静态变量初始化,所以初始化j,非静态代码块,然后调用构造函数,t2亦是如此,最后类编译完后,进入main函数,执行t,t初始化前先将Test中非静态变量初始化,然后调用构造函数
按照上面的解析,可以理解,但是有一些疑问。初始化t1,newTest1()的时候会将类中的非静态变量初始化,所以初始化j,非静态代码块,然后调用构造函数,那调用newTest1()的时候,按照先初始化静态,然后初始化非静态的顺序,不久又要初始化t1了么?这样不就又进行了不断的循环了么?这块儿很不理解。不是一定要先把静态都初始化完,才初始化非静态么?
真诚的请大牛指点!!!
------解决方案--------------------
简单来说静态变量和静态代码块优先执行,而在静态变量和静态代码块中的方法不会再去执行类中的静态变量和静态代码块,静态的东西都只加载一遍,所以是先加载public static Test t1=new Test("t1"); 而在实例化过程中不会再去加载静态的变量和代码块,以此类推
------解决方案--------------------
这个问题应该分为编译Test类,跟实例化Test:
1.编译Test类:
测试方法把
// public static Test t1=new Test("t1");
// public static Test t2=new Test("t2");
// Test t=new Test("init");
都注释了,运行结果会是:
1:i i=0 n=0
2:静态块 i=1 n=99
没有输出j相关的,那是因为j是成员变量,非静态成员变量。也就是说在不实例化Test的条件下,加载顺序是静态变量,静态块。
2.当有实例化的Test静态变量存在的时候。
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;
private 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");
}
}运行结果:
1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
4:i i=3 n=3
5:静态块 i=4 n=99
这说明,在实例化Test类的时候,先初始化的并不是静态变量,而是成员变量,最后加载的静态变量,跟静态快。
但我们在把public static int i=print("i"); 移到public static Test t1=new Test("t1"); 之前运行结果:
1:i i=0 n=0
2:j i=1 n=1
3:构造块 i=2 n=2
4:t1 i=3 n=3
5:静态块 i=4 n=99
说明静态变量的初始化顺序跟位置有关系。
------解决方案--------------------
public class Test {
public static int k=0;