先看代码
class Parent {
int i = 1;
Parent() {
System.out.println(i);
int x = getValue();
System.out.println(x);
}
{
i = 2;
}//这个叫构造块
protected int getValue() {
return i;
}
}
class Son extends Parent {
int j = 1;
Son() {j = 2;}
protected int getValue() {return j;}
}
class Test {
public static void main(String[] args) {
Son son = new Son();
System.out.println(son.getValue());
}
}
我本来以为上述代码输出是1,1,2。
原因是:new son时,会先初始化parent,parent最开始将i赋值1,然后执行构造函数,输出1;然后继续往下走,getvalue得到1并输出1,最后将i赋值2。然后son.getValue()的时候,j=2这个先会在构造函数执行。所以最后输出2.
但是真实情况是:对parent进行初始化时,先执行 构造块,将i赋值2,然后输出2;接着调用getvalue的时候,调用的是son的getvalue,此时j没有初始化,j=0。最后调用son.getValue()的时候,son已经被初始化了,输出2.。所以正常的结果是2,0,2.
这里涉及到知识盲区就是说:如果子类覆盖了父类的方法,则在构造函数中, 调用的方法也是子类的 。
另外还有一段代码
// 程序B
public class MagimaTest {
public static void main(String[] args) {
magimaFunction();
}
static MagimaTest st = new MagimaTest();
static {
System.out.println("1");
}
{
System.out.println("2");
}
MagimaTest() {
System.out.println("3");
System.out.println("a=" + a + ",b=" + b);
}
public static void magimaFunction() {
System.out.println("4");
}
int a = 110;
static int b = 112;
}
我本来以为输出是:
1
4
3
a=0,b=112
但是实际上是:
2
3
a=110,b=0
1
4
在执行main之前,需要初始化MagimaTest类。
先执行static MagimaTest st = new MagimaTest();
然后执行构造函数,但是在开始之前先执行构造函数。此时输出2.
初始化a
然后执行构造函数,此时a=110,b未初始化。输出3; a=110,b=0.
然后st成员变量初始化结束,执行下一个static。输出1.
继续初始化下一个static 变量b
最后调用magimaFunction 输出4.
在进行static MagimaTest st = new MagimaTest();时,下面的static不进行初始化,需要先将MagimaTest的构造步骤完成。因此a会在b前面进行赋值。