The Artima Developer Community
Sponsored Link

Java Answers Forum
Need Help on order of constructors calls

3 replies on 1 page. Most recent reply: Aug 13, 2004 7:00 PM by rassuls

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 3 replies on 1 page
rassuls

Posts: 10
Nickname: rassuls
Registered: Mar, 2003

Need Help on order of constructors calls Posted: Aug 13, 2004 8:31 AM
Reply to this message Reply
Advertisement
The following code and it results are:
class A
{
    public int varA;
    public A()
    {
        doSomething();
    }
    public void doSomething()
    {
        System.out.println("AAA");
    }
}
 
public class B extends A
{
    public int varB = 1111;
    public B()
    {
        doSomething();
    }
    public void doSomething()
    {
        System.out.println("varB="+varB);
    }
    public static void main(String[] args)
    {
        new B();
    }
}


varB=0
varB=1111

From the A class constructor the doSomething of B class method is called even though B object is not created yet. Can you explain this process? In advance I appreciate your help.
Thanks
Russell.


Kishori Sharan

Posts: 211
Nickname: kishori
Registered: Feb, 2002

Re: Need Help on order of constructors calls Posted: Aug 13, 2004 5:13 PM
Reply to this message Reply
Here is what happens when you instantiate a class as:

new B();

1. JVM determines the memory that is needed to hold the values(or references ) of instance variables of this class. The instance varibles from ancestor classes are also included in the list.
2. JVM allocates the memory determined in STEP 1 + some extra memory to store info about the object. This extra memory depends on JVM implementation. For example, Sun JMV uses 3 machine words always, whereas IBM JVM uses 2 machine words for all objects except arrays. For an array object, IBM JVM also uses 3 machine words.

3. All instance varibles are assigned their default values. That is, primitives numerics are assigned zero, boolean false and reference types null.

4. At this stage object exists in memory with all its instance variables having their respective data type default values. The object referene is represented by keyword "this".

5. Then this "this" is passed to the constructor being called with new operator. In your case, the call new B() is replaced by
new B(this);

Here, this is nothing but the reference of object created in STEP 1,2.

6. The constructor of B is called. JVM determines that B is inherited from A. So, before it starts executing construtor of B, it calls the constructor of A passing the argument "this". So, now A(this) is invoked, where "this" is nothing but the reference to an object of B created in STEP 1, 2.

7. When A(this) is called, JVM determines that class A is inherited from java.lang.Object class. So, JVM repeats the STEP 6 and the constructor of Object class, Object(this) is called. Again, "this" in Object(this) is the reference to object of clss B created in STEP 1,2.

8. When Object(this) , that is, the constructor of Object class is invoked, then JVM determines that there is no ancestor of Object class. At this time, JVM assigns the initial values to the instance variables of Object class. Note that, this assignment of initial values uses the user suppllied initial values. That is, if an instance variable is:
int a = 101;
then 101 is assigned to a in this step. However, zero was assigned to a in STEP 3.

(At this time, JVM executes the non-static initilaizer for Object class, if any). We will ignore this step in our discussion.

Now, JVM completes the constructor call to Object (this).

9. The control returns to A (this) call. Before, JVM starts executing any of the code in A() construtor, it initializes all instance variables defined in A with user supplied values.
Now code inside A() construtor is excuted. Note that A() gets a hidden argument "this". In fact, A() is A (this) and we know that "this" is a reference of an object of class B created in STEP 1,2. So, when doSomething() in A() is excuted it is excuted as this.doSomething() and "this" is an object of B, where B has overriden doSomething() method. So, doSomething() of B class is executed. Note that this is possible only because in STEP 1, 2, an object of class B was created. Constructor is just a chance given to programmer to initialize the instance variables of that object.

10. Now, control comes to B(this). JVM initializes of instance variables of B and then executes this.doSomething(). Since B's instance variables were initialized at this time when doSomething() was called you get 111 printed, whereas when doSomething() was called in STEP 9, you get 0 printed.

The main point you need to note is that an object is created with default values for instance variables well before the construtor is called. It is the "new" operator that creates the object and then constructor is called. It is also advisable not to call methods from inside constructor. The reason is that your object may not be initialized the way you intendd to. For example, in your case, you always wanted to see 111 printed whenever doSomething() on B's object is called. Howveer, because of the order of initailization of objects, you saw different results.

Thanks
Kishori

Kishori Sharan

Posts: 211
Nickname: kishori
Registered: Feb, 2002

Re: Need Help on order of constructors calls Posted: Aug 13, 2004 5:16 PM
Reply to this message Reply
Forgot to add the example tin previous post. Run class B and you will get messages printed that will assist you in visualizing the process of object cretion.
class A
{
    public int varA;
    String s1 = A.init ("Initializing A");
    {
      A.init("A non-static initaLIZER");
    }
    public A()
    {
      A.init("Constructor A Started");
      System.out.println("Inside A constructor: " + this.getClass().getName());
      doSomething();
    }
    public void doSomething()
    {
        System.out.println("AAA");
    }
 
    public static String init( String s ) {
      System.out.println(s);
      return s;
    }
}
 
 
public class B extends A
{
    public int varB = 1111;
    String s1 = A.init ("Initializing B");
    public B()
    {
        A.init("Constructor B Started");
        doSomething();
    }
    public void doSomething()
    {
        System.out.println("varB="+varB + " : String is: " + s1 );
    }
    public static void main(String[] args)
    {
        new B();
    }
}
 
 

rassuls

Posts: 10
Nickname: rassuls
Registered: Mar, 2003

Re: Need Help on order of constructors calls Posted: Aug 13, 2004 7:00 PM
Reply to this message Reply
Thank you Kishroi Sharan. I appreciate your help, it was very helpful.
Russell

Flat View: This topic has 3 replies on 1 page
Topic: need FileInputOutputStream Previous Topic   Next Topic Topic: Difference between abstract class and interface in the desingn perspective

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use