java中创建子类对象时会不会创建父类对象

答案是:创建子类对象时不会创建父类对象。

我们创建子类对象时,只是说创建了父类空间,并进行了初始化。如果说创建子类的时候就会创建它的父类,那内存空间中不都是Object类的对象吗?(想想java的设计师也不会这么做的)

下面转自知乎

作者:祖春雷
链接:https://www.zhihu.com/question/51920553/answer/128761716
来源:知乎

这个问题主要涉及到java对象的内存布局。

java对象的内存布局是由对象所属的类确定。也可以这么说,当一个类被加载到虚拟机中时,由这个类创建的对象的布局就已经确定下来的啦。

Hotspot中java对象的内存布局:
每个java对象在内存中都由对象头和对象体组成。

对象头是存放对象的元信息,包括该对象所属类对象Class的引用以及hashcode和monitor的一些信息。
对象体主要存放的是java对象自身的实例域以及从父类继承过来的实例域,并且内部布局满足由下规则:
规则1:任何对象都是8个字节为粒度进行对齐的。
规则2:实例域按照如下优先级进行排列:长整型和双精度类型;整型和浮点型;字符和短整型;字节类型和布尔类型,最后是引用类型。这些实例域都按照各自的单位对齐。
规则3:不同类继承关系中的实例域不能混合排列。首先按照规则2处理父类中的实例域,接着才是子类的实例域。
规则4:当父类中最后一个成员和子类第一个成员的间隔如果不够4个字节的话,就必须扩展到4个字节的基本单位。
规则5:如果子类第一个实例域是一个双精度或者长整型,并且父类并没有用完8个字节,JVM会破坏规则2,按照整形(int),短整型(short),字节型(byte),引用类型(reference)的顺序,向未填满的空间填充。

以上就是java对象的内存布局的规则。

接下来说一下java对象的实例化方法,也就是常见的<init>方法。
当我们new一个对象时,其实jvm已经把这个对象的整个空间已经分配好,并且整个对象的实例域布局已经确定下来啦。
实例化方法<init>就是将对象实例域的值设置到相应空间中。

<init>方法以调用父类的<init>方法开始,以自身构造方法作为结束。实例域的声明与实例初始化语句块的位置关系会影响编译器生成的<init>方法的字节码顺序。

还是以一个例子说明一下:
class Parent {
private short six;
private int age;
}

class Sub extend Parent{
private String name;
private int age;
private float price;
}

当前Sub对象的内存布局由下:
&amp;amp;lt;img src=&quot;https://pic1.zhimg.com/50/v2-4ce1b61927241c3d7eea75248900b552_hd.jpg&quot; data-rawwidth=&quot;317&quot; data-rawheight=&quot;421&quot; class=&quot;content_image&quot; width=&quot;317&quot;&amp;amp;gt; super所谓的父类存储空间的表示到底是什么意思?
这里的super存储我想就是绿色的那个位置吧!

在java继承中,我们说子类继承了父类的所有属性和方法,但是有不能直接使用父类中的private属性和方法。这是不是矛盾呢?

其实这并不矛盾,通过上面的java内存布局我们知道,子类确实继承了父类的所有属性和方法,即拥有了父类的所有的属性和方法,但是拥有不代表可以使用。

比如说:你在银行存了5年的定期存款,这些钱是你所拥有的,但是你现在不能使用它。


  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值