Memory Space Allocation and subclasses

M

Marc Twain

This is a bit of a tricky question... but I'm sure the gurus among you
will know the answer :)

From the reference I learned that when an object is created, the
following occurs:

1- The memory space is allocate and initialized to default
2- Explicit initialization is performed
3- A constructor is called.

So far, so good. Now what happens when dealing with subclasses? I
would assume that step 1, 2 are executed for the current class, then
step 3 kicks in. Now because this is a subclass, the parent
constructor is called as the first line in the constructor block,
either implicitly or explicitly (if the 'no arg' constructor in the
parent class is absent).

Then the parent class would go through steps 1, 2 and 3 again.

Sounds good? Well the reference states something different. It says
that step 1, 2, 3 occur for the subclass, then after the call to the
parent constructor ONLY step 2 and 3 kick in for the parent class.
Which does not make any sense, since step 2 (Explicit init of the
member variables) cannot take place without step one (Memory space
allocation?).

So what it is? Does Java magically traverse the class hierarchy in
Step one, looking for any possible parent variables? Or is this just a
typo?

TIA,

AJ
 
O

Oscar Kind

Marc Twain said:
This is a bit of a tricky question... but I'm sure the gurus among you
will know the answer :)

From the reference I learned that when an object is created, the
following occurs:

1- The memory space is allocate and initialized to default
2- Explicit initialization is performed
3- A constructor is called.

This is also correct for subclasses, but maybe it is slightly clearer
if you read it thus:
1. Allocate the memory needed for the entire structure (its own fields,
the fields of the superclasses, etc.).
2. Execute the initializer blocks (these include explicit
initializations, but there are more possibilities) of Object and its
subclasses along the path to (and including) the current subclass
(every class is a subclass of Object).
3. Execute the constructor of the current class (which executes the
constructors of the superclass in the order you indicated).

Note however, that I may be wrong about the order the code is executed
for points 2 and 3. I didn't test it.


Oscar
 
C

Chris Uppal

Marc said:
1- The memory space is allocate and initialized to default
2- Explicit initialization is performed
3- A constructor is called.

So far, so good. Now what happens when dealing with subclasses?

The way it works is that given:

class Base
{
String baseExplicit = "Step1";
String baseOther;
Base() { baseOther = "Step2"; }
}

class Derived
{
String derivedExplicit = "Step3";
String derivedOther;
Derived() { derivedOther = "Step4"; }
}

The various variables are initialised in the order implied by the "Step X"
values. I.e. When a Derived is created, first the store is allocated and set
to the default values of the fields (nulls in this case), then the Derived
constructor is called. This method's first step is to invoke the superclass
constructor which will first set baseExplicit, and then start executing the
body of that constructor, thus setting baseOther. Then control returns to
the Derived constructor; it will set derivedExplicit, and then start executing
the code you supplied, and so derivedOther will be set last of all.

I.e. the compiler insetrs code for implementing explicit initialisation after
the call to the superclass constructor and before the "real" body of the
constructor.

That means that during the execution of a superclass constructor, any methods
that are called in the derived class (i.e. which override some method in the
base) will see the default values of any explicitly initialised fields. Which
can be unexpected...

<Advanced note>
There are a couple of subtleties. One is that int/String/boolean/char fields
declared final and initialised to a constant, are inlined by the compiler,
so code in the derived class will always "think" it's seeing the explicitly
initialised value, even if it is invoked from the superclass constructor. The
other is that inner classes have an implicit "hidden" field that refers to
their outer object; that (following the above logic) would not be set until
after the inner class's parent constructor had completed; however that
behaviour would break the intended semantics of inner classes so starting with
JDK 1.4 (apparently it required a change to the verifier) the synthetic "outer"
field is supposed to be set before the superclass constructor is called.
</Advanced note>

I'm not absolutely sure that I'm answering your question here, but HTH
anyway...

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top