java父子类在内存中以何种形式关联

最易理解的一种方式是,创建对象时先实例化父类对象,然后实例化子类对象,将父类对象引用当做子类对象的属性赋值给子类对象。而这个属性名称当简单理解为super(隐式的对象组合?)

创建有父类的子类的对象时,是不是在内存中会创建2个对象,一个指向子类一个指向父类?


为了验证这种假设,以下为根据<深入理解java虚拟机>而得来的理解

对于只需要应用这种特性的开发人员来说,这种解释比较简单

而实际到底是怎样的呢?

这种继承关系可以从2个方面解释

一是类的继承关系

二是是当创建子类对象时,这种关系在内存中是如何实现的


1.类的继承关系
在<深入理解java虚拟机>,讲到Class类文件的结构,其结构中包含了这里讲到的继承关系

this_class
super_class
interfaces

这里的super_class存储的就是该类的父类,所以jvm硬编码实现了这种继承特性。通过super_class可以找到父类的全量名


字段表集合: 字段表集合中不会列出从超类或者父接口中继承而来的字段,但有可能列出原本java代码之中不存在的字段,譬如在内部类中为了保持对外部类的访问性,会自动添加指向外部类实例的引用 p178


方法表集合:与字段表集合相对应的,如果父类方法在子类中没有被重写, 方法表集合中就不会出现来自父类的方法信息





2.这种继承关系在对象中是如何体现的?(隐式的组合?)
<深入理解java虚拟机>中讲到,对象在内存中(堆)分为3块区域:对象头(Header),实例数据(Instance Data)和对齐填充(Padding)

对象头中(Header)与继承关系有关的就是类型指针, 通过该指针查找其类元数据的指针。而通过instanceof运算符时,可判断是否为父类实例,我想这里是通过类的继承关系super_class来判断的,而不是通过对象来体现父子关系的


实例数据(Instance Data)
<深入理解java虚拟机>中讲到,无论是从父类继承下来的,还是在子类中定义的,都需要记录在实例数据模块中。
这里有2个解释:
一种是创建了父类的副本
可以理解为创建子类对象时,父类中对象的变量也会在子类中创建一个相同的副本,这2份变量创建完之后,应该是没有关系了,互不影响(符合以上隐式组合的假设)

第二种解释: 这些变量就是父类的变量,super指向的变量就是这部分变量(并没有创建父类对象实例)

通过从其他文章或论坛得到的信息,这里偏向第二种解释。
那super.方法名该怎么解释呢,通过类文件结构中super_class来找到方法?


<深入理解java虚拟机>中并没有显式讲到this super是什么?




参考:
java中,创建子类对象时,父类对象会也被一起创建么?
https://www.zhihu.com/question/51920553

java 的继承原理
http://blog.csdn.net/tangtang5156/article/details/44218919

从原理来理解继承关系的类初始化和实例化的顺序:
https://my.oschina.net/xpbug/blog/111371

猜你喜欢

转载自newjava-sina-cn.iteye.com/blog/2387654