Reputation: 137
There is a code which is given as a task for a junior Java developers. I use Java during five years and this piece of code completely confusing me:
public class Main {
String variable;
public static void main(String[] args) {
System.out.println("Hello World!");
B b = new B();
}
public Main(){
printVariable();
}
protected void printVariable(){
variable = "variable is initialized in Main Class";
}
}
public class B extends Main {
String variable = null;
public B(){
System.out.println("variable value = " + variable);
}
protected void printVariable(){
variable = "variable is initialized in B Class";
}
}
The output will be:
Hello World!
variable value = null
But if we change String variable = null;
to String variable;
we will have:
Hello World!
variable value = variable is initialized in B Class
The second output is more clear for me. So, as far as I know the sequence of inizialisation in Java like this:
Also there is post which describes the behavior of the this
keyword in context of a superclass - Calling base class overridden function from base class method
Based on the rules given above, I assume to have sequence like this:
B
;Main
;main.variable
with null;Main
;b.printVariable()
in class Main
; (Why doesn't it call main.printvariable
? We don't have this
key word here.)b.variable
"variable is initialized in B Class"B
;b.variable
with null value, am I right?;B
executedPlease, can someone give a complete and full explanation of how this inheritance inizialisation sequence works. And why changing String variable = null;
to String variable;
leads to another output.
Upvotes: 5
Views: 4730
Reputation: 12376
This is a nice exercise! But it's not a fair question to ask junior developers. This one is for seniors. But to make this text useful during the technical interview, I'd modified it by adding an argument to the Main's constructor:
public Main(String something){
printVariable();
}
If the person will answer what will happen, then remove the argument and ask the original questions. If the person won't answer - there is no need to continue - s/he is junior.
You can also remove the protected qualifier in class B and ask what will happen if you have a goal not to hire this person :)
Upvotes: 1
Reputation: 6980
First, you need to understand, what happens when you write variable = null;
. When is that code executed. This basically determines the output.
Before I begin, I should also mention that when you create an object of class B
, the printVariable()
function of the main class is not called. Instead, always the printVariable()
of B will be called.
Keeping this in mind, when you have variable = null
, the execution for B's constructor will begin. First Main()
will be called, which will call the printVariable() method. At last, variable=null
, will be called overwriting the variable
variable.
In the other case, where you do not initialize variable=null
, the variable
set by the printVariable()
function will not be overwritten, hence you get what you were expecting.
In summary, this is the order of execution of statements, when you do new B()
:
Main() //super constructor
B#printVariable()
initializtion of variables in B's constructor (if any) [i.e. variable=null, if present]
Upvotes: 2
Reputation: 1315
The sequence is:
So basically, the super object Main() is constructed before any intialisation events of class B. Which means variable=null occurs later. This makes sense as otherwise B could break the initialisation of Main.
Joshua Bloch covers a lot of good ground in his effective java book about how dangerous inheritance is to get right, I would recommend it.
Upvotes: 9