0

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?

Community
  • 1
  • 1
MengT
  • 1,207
  • 2
  • 14
  • 16
  • 2
    There is only one instance, i.e. one object. The object, however, is made of two parts, one with the stuff coming from the parent, and another with the stuff it brings itself. Don't see any need for Oracle to write a paper about this, though. – gd1 Oct 05 '14 at 11:30
  • It's like an onion -- each layer is a class, with `Object` innermost, then each superclass in turn until you get to the "real" class. (This is how the vast majority of object-oriented languages work.) – Hot Licks Oct 05 '14 at 11:57

4 Answers4

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:

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.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
  • One needs to understand that a "constructor" is called *after* the object is allocated and does not *cause* allocation. So when you do `new SubClass()`, the space for both SubClass and SuperClass (and Object) is allocated as one "lump", with the instance variables for all the classes lined up one after the other. Then the constructors are invoked to initialize the instance variables for each class. – Hot Licks Oct 05 '14 at 12:14
  • (If you look at the bytecodes there is a `new` operation, to allocate the object, then an `invokespecial`, to call the constructor. The `new` operation looks in the "outermost" class description to find the size of the *entire* object (including all superclasses) and allocates that much storage.) – Hot Licks Oct 05 '14 at 12:18
  • @HotLicks That is what I tried to explain. It is very well explained at the second link. Is my answer transmitting he contrary? ("As the second link's site states: Is new who creates the object. That is: It reserves memory for all the class references") – Pablo Francisco Pérez Hidalgo Oct 05 '14 at 12:19
  • No, was just attempting to further clarify/restate what's going on. In particular, it's often not understood that the *allocation* of the object and it's *initialization* are two separate steps, and the *allocation* is largely hidden. – Hot Licks Oct 05 '14 at 12:21
  • @HotLicks Thanks, not being an English native speaker implies sometimes I am afraid I am not transmitting the idea correctly. – Pablo Francisco Pérez Hidalgo Oct 05 '14 at 12:23
  • @HotLicks, yeah, I agree and understand what you said, but I still need some firm evidence to convince myself. Could you please tell me how to check the bytecodes? – MengT Oct 05 '14 at 13:04
  • 1
    @Truman'sworld - Well, if you don't take my word for it (I wrote most of the "classic" JVM for the IBM iSeries), you can compile a program with `new` in it and do `javap -c MyClassName.class` from the command line. – Hot Licks Oct 05 '14 at 13:07
  • @Truman'sworld - Also, with that tool you can examine the constructors for several classes. In the `` methods (which is how constructors are identified) you will always see an `invokespecial` of the superclass `` method, either because the programmer did a `super` call in the constructor, or because, lacking such a call, the compiler supplied one implicitly. – Hot Licks Oct 05 '14 at 13:12
  • @HotLicks, forgive my stubbornness, I respect and thank your explanations. I just want to check it myself. – MengT Oct 05 '14 at 13:26
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.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
0

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.

Murtaza Zaidi
  • 599
  • 3
  • 14
  • Yes and no. Within the derived class instance are virtually all of the components of a base class instance. – Hot Licks Oct 05 '14 at 13:14
  • True but an object of derived class even if it contains all the attributes and methods of a base class is not the object of base class. – Murtaza Zaidi Oct 05 '14 at 13:25
  • Not completely true. An object of the derived class will return `true` if asked if it's an `instanceof` the base class. – Hot Licks Oct 05 '14 at 13:29
  • It means instance of derived class is also an instance of parent class even if parent class is abstract? – Murtaza Zaidi Oct 05 '14 at 14:04
0

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.

Silly Freak
  • 4,061
  • 1
  • 36
  • 58