深入理解Java虚拟机总结-对象的创建过程

今天同学问我下面的代码,输出结果为什么会是那样.查阅资料之后,终于给了她答案,我也对Java中对象的创建过程有了更深的理解.

有两个问题:

  • 为什么调用Parent的构造器时,里面调用的printName()方法却是Child的?
  • 为什么调用Parent的构造器时,printName()方法输出的是null?

我们先介绍一下对象的创建过程:

  • 查看对应的类是否被加载过,如果没有被加载过,那么就先执行对应类的加载过程
  • 为对象分配内存空间
  • 将此内存空间初始化为零值
  • 执行invokespecial来调用类的构造函数
    • 先调用父类的构造函数
    • 对类的实例变量赋初值
    • 继续执行类的构造函数

我们拿上面的例子来解释一下这个过程:

  • 首先,加载类Child,在连接阶段,发现还有父类没有被加载,就去加载父类Parent
  • 为Child类的对象分配内存空间
  • 将Child类对象的内存空间初始化为零值
  • 调用Child类对象的构造函数
    • 先通过super()调用父类的构造函数
    • 再对Child类对象的name实例变量进行初始化,初始化为"child"
    • 调用Child类实例构造器中剩下的语句,即printName()

我们先解释为什么调用Parent的构造函数时,其中调用的printName()方法是调用的Child的printName()方法.

在调用Parent的构造方法时,当调用printName()方法时,实际上调用的是this.printName(),而此时this是啥呢?是上面我们提到的那个Child类的对象.从Child的类的字节码中我们就能看到:

那么为什么第一行输出的name是null呢?

从上面的过程中,我们可以看到,由于是先调用父类的构造函数,随后对Child类对象的name实例变量进行初始化,所以上面输出的是null.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 写在之前 因为简书字数限制,完整版地址:https://www.zybuluo.com/hainingwyx/no...
    hainingwyx阅读 14,016评论 0 41
  • 一、运行时数据区域 Java虚拟机管理的内存包括几个运行时数据内存:方法区、虚拟机栈、本地方法栈、堆、程序计数器,...
    加油小杜阅读 1,539评论 1 15
  • 1.运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域...
    adison阅读 2,488评论 1 43
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,767评论 18 399
  • 额,今天是2017年2月2号,大年初六。 今天为了天梯玩荆轲上分,做各种任务赚金币买荆轲。终于买到荆轲之后,发现玩...
    乐小Pi孩_VoV阅读 192评论 0 0