关于继承的内存图我们可以通过具体代码讲解:
首先测试类的main()方法和class文件加载到方法区,main()方法被虚拟机调用入栈,执行main方法中第一句代码,将类Zi的字节码文件和变量加载到方法区,有类Zi继承了Fu类,所有Zi类会把Fu类的class文件和变量加载至方法区,同时Fu类继承object类,所以object的class文件也会被加载。如下图所示:
接着执行等号左边,Zi z加载入栈,等号右边在堆内存中开辟一个空间,与之前不同的是,该空间被一分为二,一边加载父类的成员变量,一边则是自己的成员变量。对于生成的变量各自赋上初始化值。并将地址赋值给栈中的变量。
接下来,sout(z)则输出的是地址值001,对于z.age=23以及后两句,将23赋值给Z的name,Z地址为001,通过001找到Z 的地址,该地址分为两块,先在右边子类找成员变量age,若没有在父类一侧找成员变量。
最后main出栈,此时无指向堆内存的变量,堆内存被清理回收!
对于包含私有成员变量的情况
对于包含私有成员变量的情况内存图大部分与非私有的相同,但是在一些地方存在差异。差异在sout(z);之后,在此行代码之前,内存原理与上述情况一样,现分析之后的代码。
z.name="钢门吹雪";z.age=25;执行这两行代码时,同样通过001找到Z 的地址,该地址分为两块,先在右边子类找成员变量age,若没有在父类一侧找成员变量。但是此时name和age为父类的私有成员变量因此在堆内存中不能找到该变量,所以系统会报错。
除此之外,皆与非私有一样。