继承和对象创建,理论和实际

时间:2012-08-06 23:02:33

标签: java inheritance memory-management

假设我有一个班级A.java

enter image description here

当我执行A的构造函数方法时,它将为xyz Object创建一个内存空间。

A xyz = new A();

对内存的引用可能类似于

[xyz] ---> '0x34524'

这是OOP的基础知识。很简单!

现在,

如果一个类继承自不同的父类会发生什么?将在内存中创建多少个对象空间?

让我们说,

enter image description here

然后我们创建一个类D.java的对象,

D omg = new D();

在这里,我们知道D的对象将调用C.java的构造,依此类推,直到A.java。这是否意味着在内存中我们有4个不同的内存引用,因为我们实例化了所有这四个对象(一个是直接的,另一个是间接的三个)?

[omg] ---> '0x34525'
[C]   ---> '0x34526'
[B]   ---> '0x34527'
[A]   ---> '0x34528'

注意:

  1. 这不是作业问题,这只是一个好奇心问题。
  2. 我知道如果我们在A.java中有一个实例变量,那么我们不会只创建对象A,但只要我们点击new关键字,我们就会创建其他内部对象。

3 个答案:

答案 0 :(得分:4)

首先,tid位...调用对象​​的构造函数不会分配它。在字节码中,初始化new Object()表示为......的效果

new java/lang/Object
invokespecial java/lang/Object <init>()V

new指令负责分配空间并获取对未初始化对象的引用,而invokespecial句柄调用构造函数本身(在内部编译)到void method named <init>,因此descriptor <init>()V)。

继续,对象分配的内部和representation on the heap are entirely JVM specific。但是,据我所知,每个分配的对象只有一个分配的对象,无论它的超类数量如何。内存中的对象本身具有用于其自己的类及其超类的实例字段的空间。它还必须有virtual method table的空间,以便在对对象执行虚拟方法调用(例如,通过invokevirtual)时进行虚拟调度。

在内部,Oracle HotSpot JVM管理名为 oops 或普通对象指针的内容。您可以阅读有关HotSpot内存布局here的更多信息。随意browse the HotSpot source repository

答案 1 :(得分:1)

JVM仅为一个对象分配内存(此处为D)

  1. 内存分配和初始化发生在底部(此处为D)到顶部(对象)
  2. 初始化/调用构造函数发生在Top(Object)到Bottom(这里是D)
  3. 参考:

    http://www.artima.com/designtechniques/initialization.html

答案 2 :(得分:0)

除了我的经验之外,我还没有读到这个。 当您致电new D()时,构造函数链开始,首先创建java.lang.Object,然后extends创建A,我的意思是创建Object后(它是所有对象的根),A在其上初始化,为A的成员添加内存,包括字段和方法(指向某些代码的指针!)。然后是extends到B等等。

如果方法被覆盖,在扩展过程中,对象中的方法指针将指向新代码。

这只是D的一个参考。