有段代码如下:
public class TestA
{
TestA()
{
System.out.println("P ");
this.init();//为什么this.init()调用的是已经被覆盖了的子类的init()了,而不是当前TestA的init()呢???
}
void init()
{
System.out.println("Q ");
} public static void main(String[] args)
{
TestB testb=new TestB();
}
}class TestB extends TestA
{
int i=1;
TestB()
{
super();
System.out.println(i+" ");
}
void init()
{
System.out.println("C ");
this.i=2;
System.out.println(i+" ");
}
}运行后输出为:
p q 2 1
public class TestA
{
TestA()
{
System.out.println("P ");
this.init();//为什么this.init()调用的是已经被覆盖了的子类的init()了,而不是当前TestA的init()呢???
}
void init()
{
System.out.println("Q ");
} public static void main(String[] args)
{
TestB testb=new TestB();
}
}class TestB extends TestA
{
int i=1;
TestB()
{
super();
System.out.println(i+" ");
}
void init()
{
System.out.println("C ");
this.i=2;
System.out.println(i+" ");
}
}运行后输出为:
p q 2 1
这么说的话,this并不代表其所在的当前类了??例如本题中this虽然写在TestA中,但它真正代表的是TestB而不是一般我们认为的TestA??这就是我觉得别扭的地方。是吗?如何理解这个怪异的现象呢?谢谢。。
你也知道B覆盖了A的init方法,所谓覆盖,就是说盖上了不显示出来,所以A的init方法就不能显示出来咯
所以输出了C 2
后面那个1才是值得琢磨的东西!~
对啊,1是因为先super()后再进行初始化。
可是对目前本题中this虽然写在TestA中,但它真正代表的是TestB而不是一般我们认为的TestA这个问题非常别扭!转不过弯来。
而且你在B类重写了A类的init()方法,那必然是先找到子类的重写的init()方法(包含你把 i 的值 负成2),但你在B类的构造方法里输出了i (这个时候i的值是1)
所以输出是 p c 2 1
你创建一个子类对象后
在子类调用父类构造方法的时候
由于this始终是指向当前对象自己的(这里是指testb)
父类的this隐藏了
变成了super.this
{ TestB2()
{
super();
i = 1;
System.out.println((new StringBuilder(String.valueOf(i))).append(" ").toString());
} void init()
{
System.out.println("C ");
i = 2;
System.out.println((new StringBuilder(String.valueOf(i))).append(" ").toString());
} int i;//把你的对i的初始化放到了构造函数里边,所以结果变为了1.
}
1:父类的静态成员,静态块
2:子类的静态成员,静态块
3:父类的非静态成员,非静态块,构造函数
4:子类的非静态成员,非静态块,构造函数
实际是在第四步,父类的构造函数执行完毕后就会执行int i=1;
然后是TestB的构造函数。执行
System.out.println(i+" ");
输出结果为1
初始化的顺序问题
1:父类的静态成员,静态块
2:子类的静态成员,静态块
3:父类执行构造函数,在构造函数中执行非静态成员,非静态块.
4:子类执行构造函数,在构造函数中执行非静态成员,非静态块.之所以我自己这样认为,因为ZiSheng在16楼贴出来的反编译代码里已经显示了,非静态成员的初始化是在构造函数中进行的.
TestA()
{
System.out.println("P ");
String s=this.getClass().getName();
System.out.println(s);//这里的s居然是TestB.为什么
this.init();//为什么this.init()调用的是已经被覆盖了的子类的init()了,而不是当前TestA的init()呢???
}