Does a superclass instance also being created when

2020-08-03 04:54发布

问题:

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.

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?

回答1:

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

  • 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

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.

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

  • Virtual method pointers for Object
  • Virtual method pointers for BaseClass
  • Virtual method pointers for DerivedClass

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.

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.



回答2:

When you create a new instance and the class constructor is called, enough memory is being reserved in the heap for that instance's attributes to be stored. Those attributes comprise both:

  • Attributes directly belonging to your class definition;
  • Attributes belonging to all upper nodes in your class hierarchy tree.

Yes, the superclass constructor is called, but with the sole purpose to initialize attributes of the superclass. It never means a new object of the superclass will be created.

Check these links, they may help you to understand the process:

  • http://www.javaworld.com/article/2076204/core-java/understanding-constructors.html
  • http://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html
  • http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

On the second link, documentation states: It is new which creates the object. That is: It reserves memory for all the class references (Object attributes) and primitive values. Then, the constructor is called, and its aim is to initialize enclosing class' attributes. Since the object attributes are references in Java, the constructor may use new to create object attributes, their references will be the values stored in your object's memory. The superclass constructor just continues this task for your class inherited attributes.



回答3:

An object is identified by its address, stored in variables of object types. the new operator returns that address, and only one address, so there can only be one object. You can check this by looking at System.identityHashCode(this) in sub- and superclass constructor, for example.



回答4:

Base Class's object is not instantiated when a Derived Class's object is instantiated. Inheritance only brings certain attributes and methods of Base Class to Derived Class. Constructors/destructor of base class are called along with those of derived class when object of derived class is made/destroyed. But this does not mean object of base class is also made.