Reputation: 3452
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 :
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 ?
Upvotes: 5
Views: 1316
Reputation: 1503100
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.
Upvotes: 8
Reputation: 888047
Method overriding happens whether or not the derived class has been initialized.
This is why you should avoid calling virtual methods in initializers.
Upvotes: 3