5

Consider the following code segment:

class A{ /* assume static and non static block are here */ }
class B extends A{ /* assume static and non static block are here */ }

In main method,

 new B();

So the order of the initialization would be :

  1. static members initialization for class A
  2. static members initialization for class B
  3. non static members initialization for class A
  4. then execute the code inside constructor A
  5. non static members initialization for class B
  6. then execute the code inside constructor B

Now take a look at this code segment,

class A{
    A(){
        this.m(); //line 1
    }

    void m(){
        System.out.println("A.m()");
    }
  }

  class B extends A{
     void m(){
        System.out.println("B.m()");
    }
  }

In main method,

 new B();

When the code of constructor A is being executed, it can only see the method m in class A since non static members hasn't been initialized yet for class B (according to the order I mentioned). However the result is "B.m()". (method of sub class has been executed) Can someone explain what is happening here(method overridng) considering the order that I have mentioned ?

4
  • This should bring some clarity, although it's not an exact duplicate. Commented Aug 12, 2013 at 15:27
  • 1
    possible duplicate of Java Class Initialization Order And Overridden Methods Commented Aug 12, 2013 at 15:27
  • 2
    You should never, Never, NEVER invoke virtual methods in a constructor / destructor. This is definite bad, terrible idea. Invoking final instance methods can be okay, but I generally consider it a bad idea and avoid it when possible. It's such a terrible idea that it's covered in Scott Meyer's Effective C++ and while your question is about Java, the primary reasons that he gives there apply here to. Don't do it. Commented Aug 12, 2013 at 15:27
  • Also you might want to go through the Relevant JLS Section Commented Aug 12, 2013 at 15:30

2 Answers 2

8

When the code of constructor A is being executed, it can only see the method m in class A since non static members hasn't been initialized yet for class B (according to the order I mentioned).

You're assuming that methods are part of "non-static members" which are initialized. That's not the case - it's really a matter of fields in B being initialized when the A constructor is finished.

As soon as an object is created in Java, its type is set and never changes. Enough space is allocated for all the fields - but the fields are actually initialized from the top of the inheritance hierarchy down.

So yes, if you call an overridden method from a constructor, it will execute in a context where some of the fields it wants to use aren't initialized - so you should avoid doing that if possible.

Sign up to request clarification or add additional context in comments.

9 Comments

Jon, Had a quick question, Am wondering if I am taking this in the right direction; The simple way to understand this is, when we have an instance of Class B, that's the active object here. So, new B(), would call the super constructor for A(), where this.m() is equivalent to new B().m() since the method is overridden.
@JNL: Well it's not really equivalent to new B().m() because it doesn't create a new object...
Jon, Agree it does not create a new object, what I meant was, if I put that correctly, can I say this.m() would be equivalent to objectOfClassB.m() which is called in main, since the main thread which is executing the program has an object of new B(). I hope its not confusing?
@JNL: Um, I think so - but I'm not sure it's actively helpful :)
Just wanted to clarify. Thank You Jon. Appreciate it.
|
3

Method overriding happens whether or not the derived class has been initialized.

This is why you should avoid calling virtual methods in initializers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.