关于子类对象实例化是否会实例化父类对象的理解

public class Father {

    private String name;

    public Father() {

        System.out.println("调用了Father的构造器-------this指针的值为:" + this);// ③

        System.out.println("调用了Father的构造器-------this.getClass()的值为:" + this.getClass());// ④

        this.name = "父亲";// ⑤

    }

  //省略get/set方法……

}

 

public class Children extends Father {

    private int age;

    public Children() {

        super();// ②

        System.out.println("调用了Children的构造器-------this指针的值为:" + this);// ⑥

        this.age = 1;//⑦

    }

//省略get/set方法……

}

 

public class Test {

    public static void main(String[] args) {

        // 创建Children的构造器创建实例

        Children children = new Children();// ①

        System.out.println("name:"+children.getName());//

        System.out.println("age:"+children.getAge());//

    }

}

准备知识:

1、首先需要澄清一个概念:java对象是由构造器创建的吗?

很多书籍、资料中会说,是的。但是实际情况是:构造器只是负责对java对象实例变量执行初始化(也就是赋初始值),在执行构造器代码之前,该对象所占的内存已经被分配下来,这些内存里值都默认是空值——对于基本类型的变量,默认的空值就是0或false,对于引用类型的变量默认的空值就是null。

 

2、在处理java类中的成员变量时,并不是采用运行时绑定,而是一般意义上的静态绑定必须明确,运行时(动态)绑定针对的范畴只是对象的方法。(方法的话只有static和final(所有private默认是final的)是静态绑定的.)

 

3、当创建任何java对象时,程序总会先一次调用每个类非静态初始化块、父类构造器(总是从Object开始)执行初始化,最后才调用本类的非静态初始化块、构造器执行初始化。

 

此时当程序执行到①时,系统会先为父类中的私有属性在堆内存开辟空间

        注意:这里并不会实例化父类对象,仅仅是为父类中的属性在堆中开辟了一段内存空间。

然后在为子类Children在堆内存空间,此时调用父类的构造方法(不写super();的话会隐式的调用),此时通过准备知识1中我们已经知道构造方法仅仅只是负责对java对象实例变量执行初始化,而不会实例化父类。

该结论可以通过Father类的构造器中输出的this和this.getClass()结果得到佐证。

输出结果如下:

085535_ZaMt_2661376.png

    通过Father类构造器中的输入我们发现,Father类构造器中的this指向的实际是子类对象的实例。这里说明子类实例化的确不会创建父类的对象,因为如果创建了父类对象的话,那么父类对象构造器中的this指向的地址肯定就不可能是子类对象的实例了。

这时我们有可能产生一个疑惑,那就是:既然不创建父类对象的实例,那么子类中是怎么拥有(这个说法可能不够严谨,但为了方便理解不做其他讨论)父类中的属性的?

    此时我们需要结合准备知识2来说明了,在编译时java类的成员变量采用静态绑定,即成员变量被关联到了类上。此时虽然父类构造器中的this指向的是子类对象的实例,但是虚拟机在子类对象中找不到name属性的时候,就到包含该构造方法中的类去找静态绑定相应的name属性的,并为其赋值为“父亲”。所以⑧中输出的结果为“父亲”。

 

上面是我对子类对象创建过程中是否实例化父类对象的理解,如果有什么不对的地方欢迎斧正!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/blackgladiolus/blog/691582

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值