创建子类实例时是否还创建了超类实例? [英] Does a superclass instance also being created when creating a subclass instance?

查看:139
本文介绍了创建子类实例时是否还创建了超类实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我见过很多线程(例如: Java中的继承 - 创建子类的对象也会调用超类的构造函数。为什么这么说?)说在创建子类实例时不会创建超类的实例。我实际上同意这个意见。

I have seen many threads (e.g.: Inheritance in Java - creating an object of the subclass invokes also the constructor of the superclass. Why exactly?) saying that the instance of superclass will NOT be created when creating a subclass instance. I actually agree with this opinion.

但是,我找不到任何官方材料(来自Oracle)来支持这一点。我搜索了几个小时,找不到任何东西。任何人都可以向我推荐一个可靠的资源来确认吗?

However, I can't find any official materials (from Oracle) to back this up. I searched a couple of hours and cannot find anything. Can anyone refer me to a reliable resource to confirm this?

推荐答案

当创建派生类的实例时,堆分配将类似于(*):

When an instance of a derived class is created the heap allocation will be something like (*):


  • 标准JVM对象标头(带有指向 DerivedClass

  • 类的实例字段对象

  • 类的实例字段 BaseClass

  • 类的实例字段 DerivedClass

  • Standard JVM object header (with pointer to Class object for DerivedClass)
  • Instance fields for class Object
  • Instance fields for class BaseClass
  • Instance fields for class DerivedClass

因此,实际上,如果忽略 DerivedClass 实例字段,该对象看起来非常像BaseClass的实例,并且JVM可以引用该对象,就像它是BaseClass的一个实例一样,并且没有任何困难。

So in effect, if you ignore the DerivedClass instance fields the object looks remarkably like an instance of BaseClass, and the JVM can reference the object as if it were an instance of BaseClass and have no difficulty doing so.

类似地,在的DerivedClass的Class对象中是一个虚方法表,包含:

Similarly, in the Class object for DerivedClass is a "virtual method table" with:


  • Object <的虚方法指针/ code>

  • 虚拟满足hod指针 BaseClass

  • DerivedClass
  • 的虚拟方法指针
  • Virtual method pointers for Object
  • Virtual method pointers for BaseClass
  • Virtual method pointers for DerivedClass

JVM通过索引到此表中来查找特定方法进行虚拟调用,比如知道 hashValue 是方法编号5, printTheGroceryList 是方法编号23.调用方法所需的编号是在类加载并缓存在方法参考数据中时确定的。调用类,因此调用方法是:获取数字,转到实例头指向的Class对象,索引到虚方法表,拉出指针,然后转移到方法。

The JVM makes virtual calls by indexing into this table to find a specific method, knowing that, say, hashValue is method number 5 and printTheGroceryList is method number 23. The number needed to call a method is determined when a class is loaded and cached in the method reference data in calling classes, so calling a method is: Get the number, go the the Class object pointed to by the instance header, index into the virtual method table, pull out the pointer, and branch to the method.

但是当你仔细观察时,你会看到,例如 Object 组中指向 hashValue的指针方法实际指向 BaseClass 中的那个(如果BaseClass重写 hashValue )。因此,JVM可以将对象视为 Object ,调用 hashValue ,并无缝地获取 BaseClass (或 DerivedClass ,如果它也覆盖了该方法)。

But when you look closely you will see, eg, that the pointer in the Object group that points to the hashValue method actually points to the one in BaseClass (if BaseClass overrides hashValue). So the JVM can treat the object as if it were an Object, invoke hashValue, and seamlessly get the method in BaseClass (or DerivedClass, if it also overrides the method).

(*)实际上,实例字段可能会混合到一定程度,因为来自超类的对齐字段可能会在堆分配中留下来自子类的字段可以填充的空白。这只是一个最小化对象大小的技巧。

(*) In practice the instance fields may be intermingled to a degree, since "aligning" fields from a superclass may leave gaps in the heap allocation that fields from a subclass can fill. This is simply a trick to minimize object size.

这篇关于创建子类实例时是否还创建了超类实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆