先说结论,创建子类对象的时候不会创建父类对象,只是会调用父类的构造来初始化子类对象的属性。此时如果在父类的构造中引用this,这个this其实是子类对象而且是一个未初始化的对想。
上代码:首先证明父类构造中的this是子类对象,这个很简单
//父类 public class Parent { public Parent() { System.out.println("父类构造中的this="+this); } } //子类 public class Sub extends Parent { public Sub() { System.out.println("子类构造中的this"+this); } public static void main(String[] args) { new Sub(); new Sub(); new Sub(); } }
//打印结果
父类构造中的this=top.liuzhihong.polymorphic.a.Sub@1b6d3586
子类构造中的thistop.liuzhihong.polymorphic.a.Sub@1b6d3586
父类构造中的this=top.liuzhihong.polymorphic.a.Sub@4554617c
子类构造中的thistop.liuzhihong.polymorphic.a.Sub@4554617c
父类构造中的this=top.liuzhihong.polymorphic.a.Sub@74a14482
子类构造中的thistop.liuzhihong.polymorphic.a.Sub@74a14482
再来证明这个this是一个未初始化的对象,其实很好理解,调用父类构造的目的就是初始化子类对象的属性,所以肯定先有一个空的子类对象然后去父类中初始化它的属性,然后再到子类中初始化属性并调用子类构造完成最后的初始化。
只需重写toString即可证明
//父类 public class Demo { public Demo() { System.out.println("父类构造"); System.out.println("creating:" + this); } } //子类 public class DemoTest extends Demo{ private static int counter = 0; private final int id = counter++; public DemoTest() { System.out.println(this.id); System.out.println(this); } @Override public String toString() { System.out.println(id); return "DemoTest id=" + id; } public static void main(String[] args) { new DemoTest(); System.out.println("---"); new DemoTest(); System.out.println("----"); new DemoTest(); } }
//运行结果,我们发现传入父类的对象属性id始终为0,如果不是上面的结论证明了这个this就是子类对象这里可能会误解。
父类构造
0
creating:DemoTest id=0
0
0
DemoTest id=0
---
父类构造
0
creating:DemoTest id=0
1
1
DemoTest id=1
----
父类构造
0
creating:DemoTest id=0
2
2
DemoTest id=2
总结:构造器可以理解成为一个 static方法,而构造器不是用来创建对象的而是在创建对象后进行初始化属性的。而new是用来创建对象的,创建对象的过程中会调用这个构造器。
原文:https://www.cnblogs.com/chengxuyuan-liu/p/14051960.html