【问题标题】:Inheritance and Object creation, Theoretically and in Real继承和对象创建,理论上和实际
【发布时间】:2012-08-03 22:45:14
【问题描述】:

假设我有一个课程A.java

当我执行A的构造方法时,它会为xyzObject创建一个内存空间。

A xyz = new A();

对内存的引用可能是这样的,

[xyz] ---> '0x34524'

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

现在,

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

假设我们有,

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

D omg = new D();

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

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

注意:

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

【问题讨论】:

标签: java inheritance memory-management


【解决方案1】:

JVM 只为一个对象(这里是 D)分配内存

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

参考:

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

【讨论】:

    【解决方案2】:

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

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

    new 指令负责分配空间并获取对尚未初始化 对象的引用,而invokespecial 处理调用构造函数本身(内部编译为@987654323 @,因此是 descriptor &lt;init&gt;()V)。

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

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

    【讨论】:

    • 对象的字段是静态解析的,因此您可以在编译时准确知道整个对象的大小,以及每个字段的偏移量。此外,给定方法的每个覆盖总是使用相同的字段偏移量,因为字段是静态解析的。所以我不知道为什么 JVM 会瞬间吃掉四个对象而不是一个。
    • 编译器不解析字段在内存中的位置,JVM 会... Java 在内存中分配一个对象并执行从直接超类到@987654338 的超类构造函数中的代码@(在构造函数内部,也可能构造其他对象,例如用于字段初始化)。
    【解决方案3】:

    除了我的经验之外,我还没有在任何地方读过这篇文章。 当你调用new D()时,构造函数链开始,它首先创建一个java.lang.Object,然后将extends它到一个A,我的意思是在创建Object(它是所有对象的根)之后,A是通过为 A 的成员添加内存,包括字段和方法(它们是指向某些代码的指针!),对其进行初始化。然后它extends 到 B 等等。

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

    这只是对 D 的一个引用。

    【讨论】:

      猜你喜欢
      • 2014-11-26
      • 1970-01-01
      • 2013-12-25
      • 2021-06-26
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 1970-01-01
      • 2015-02-01
      相关资源
      最近更新 更多