Java 附加题
public classTest {
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;
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[]) {
Testt = new Test("init");
}
}
求输出。
【分析】:
类初始化的顺序:static变量、static代码块按顺序执行→类初始化开始→非static变量、非static代码块按顺序执行→构造函数→类初始化完毕。
即:
第一大步:new Test("init")之前,先进行“static变量、static代码块按顺序执行”。
第1步:publicstatic intk = 0;
第2步:public staticTest t1= newTest("t1");
第2.1步:非static变量、非static代码块→构造函数,即
public int j = print("j");
{
print("构造块");
}
输出:
1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
这里i和n都是类变量,默认初始值是0;
第3步:public staticTest t2= newTest("t2");类似第2步。
输出:
4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
第4步:public staticinti=print("i");
输出:7:i i=6 n=6
第5步:public staticintn= 99;
第6步:static {
print("静态块");
}
输出:8:静态块 i=7 n=99
第7步:public intj = print("j");
9:j i=8 n=100
第8步: {
print("构造块");
}
输出:
10:构造块 i=9 n=101
***************************************************************************
第二大步:到这里对于new Test("init")的“static变量、static代码块顺序执行→类初始化开始→非static变量、非static代码块”都已经执行完毕,开始执行它的构造函数。
第9步:public Test(Stringstr){
System.out.println((++k) +":" + str +" i=" + i+" n=" + n);
++i;
++n;
}
输出:
11:init i=10 n=102
总的输出:
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
***************************************************************************
对于类的成员变量有该类本身的对象的说明:
下面这种情况,Test4类的成员变量有它本身的对象,自包含性被破坏,会报“java.lang.StackOverflowError”错误。
public classTest4 {
public Test4 temp=newTest4();
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Test4();
}
}
而下面这种情况就没问题。
public classTest4 {
public static Test4 temp=new Test4();
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Test4();
}
}
再看下面这种情况:
public classTest4 {
public static Test4 temp=newTest4();
public static int a=9;
/**
*
*/
public Test4() {
// TODO Auto-generated constructor stub
System.out.println(temp==null);
System.out.println(temp.a);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Test4();
}
}
}
new Test4()执行前先执行publicstatic Test4 temp=new Test4(),由于类Test4还未被加载,所以导致temp==null,temp.a=0。然后加载Test4类,执行new Test4(),执行构造函数,此时temp!=null l,temp.a=9。为什么会temp会变化,我暂时还不清楚。