public class TestA
{
TestA()
{
System.out.println("P ");
this.init();
// System.out.println(this);输出结果竟然是 TestB的引用!不知道为什么????????
}
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+" ");
}
}
{
TestA()
{
System.out.println("P ");
this.init();
// System.out.println(this);输出结果竟然是 TestB的引用!不知道为什么????????
}
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+" ");
}
}
解决方案 »
- javamail 读取邮件内容时为什么邮件中的html内容读取不到?
- java实现音乐频谱或者波形图
- ArrayList 的问题
- 问
- 编译报错unchecked or unsafe operations
- 数据连接池的工作机制
- 想做个客户端和服务端用socket通信的小程序,请问下面的代码错在哪里?
- jbuilder写applet,用了xylayout,dataset等,怎样发布呢
- Java的arrays中的asList问题,急,在线等!!!!!!
- java程序在centos上运行会有很多固有的线程
- 求助!两个没有编译错误实现同样功能的程序,但实现结果不一样!
- 2个jsp页面传递参数(多个参数)导致错误。
TestB()
{
super();
System.out.println(i+" ");
}
中先执行父类构造方法
TestA()
{
System.out.println("P ");
this.init();
System.out.println(this);
}
于是,this是对当前对象的引用,而当前对象是TestB的对象,所以this.init()调用TestB类的init()方法。呵呵,希望没有啰嗦!
System.out.println(this);
输出的结果是一个地址,其实就是TestB这个实际对象的地址,尽管这里的this是父类TestA引用
System.out.println("P ");
this.init();
// System.out.println(this);
} 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 + " ");
}
} 然后再来分析执行过程:1.main方法中只有一个语句:TestB testb = new TestB();
看到new TestB()就去找TestB的构造器,得知TestB构造器中第一句话是super();(其实即使不写,super();也是隐式的自动添加到子类TestB构造器中的)2.看到super();顺藤摸瓜,去看父类TestA构造器,里面有两句话:
System.out.println("P ");
this.init();
第一句好说,直接打印:P
关键在于第二句this.init();
由于在父类TestA构造器中,所以此处的this是父类TestA的引用,但需要注意的是,虽然引用是父类的,但JVM栈内存中实际的对象是子类TestB的对象,因此,在执行this.init()时,JVM进行动态方法分配(dynamic method dispatch),动态方法分配,简单来说,就是根据实际对象调用相应的方法,因为之前已经解释了,这里的实际对象是子类TestB的对象,所以动态方法分配调用的是子类对象的重写init()方法。3.理解了为什么调用子类TestB的init()方法,再来看方法内部:
System.out.println("C ");
this.i = 2;
System.out.println(i + " ");
第一句也好说,直接打印:C
第二句,这里的this.i其实是属于子类对象TestB的父类部分,i暂时被赋值为2
第三句,打印此时的i值,也就是:24.父类TestA构造器调用完成后,返回到子类TestB构造器中
这时所做的第一件事情,就是对TestB对象的成员变量赋默认值,因此刚刚在父类构造器中被暂时赋值的i现在被重新赋予一个初始化值1
接下来执行打印语句:
System.out.println(i + " ");
打印结果:1综上所述,完整的代码打印结果为:
P
C
2
1