java实例_Java中,实例化子类会实例化父类么(补充篇)

前言

前几天有一个小伙伴给我留言,提出了2个疑问:

是关于这篇文章的:Java中,实例化子类会实例化父类么

  • 子类实例为什么会有父类的成员变量?
  • 它的初始化是通过哪种方式访问了父类对象中的表?(我理解这句话的意思是:子类如何访问到从父类中继承的变量或方法)

实话实说,看到这个小伙伴的问题时…我一下子懵住了,很久没有看JVM的内容,一时有些语塞…今天特地抽了些时间重新整理了一下。

因为自己在JVM这一块并没有特别深入的了解,所以这里权当一起探讨交流~欢迎一起讨论。

正文

问题一:子类实例为什么会有父类的成员变量?

这个问题,怪我并没有get到点…为什么会有?因为继承呐,继承在Java规范中的语义就是能够拥有父类中protect及以上权限的变量和方法。规范要求,不得不从~

我猜这个小伙伴可能是问另一个意思:子类通过什么样的方式拥有了父类的成员变量。

如果是这个问题,那么其实和问题二是差不多的。所以让我们从问题二中找寻答案…

问题二: 它的初始化是通过哪种方式访问了父类对象中的表?

写了俩个很简单的子/父类:

public class Son extends Father { public String nick;}public class Father { public String name;}

然后javap -v看一下Son.class:

java实例_Java中,实例化子类会实例化父类么(补充篇)_第1张图片

注意看常量池(Constant pool)里的#3。#3被映射到#14上,而#14怎是我们的Father的CONSTANT_Class_info。通过此就可以定位到我们Father,因此也就可以找到到其中的属性/方法。

换一种理解,子类的实例中已经包含了父类属性,为什么?因为此时至始至终都是一块内存空间,我们可以用一小段代码,验证这个问题:

public class Son extends Father { public String nick; public Son(){ System.out.println(super.equals(this)); }}

run起来,你会发现是true。也就是说super的引用和this的引用是同一个。既然是同一个,那就不可能是两个内存空间。

尾声

以上,是基于我理解的解答。如果有什么不妥之处,欢迎评论区指出并交流~~

你可能感兴趣的:(java实例)