I thought that the order of which class elements are loaded into the JVM are as follows:
1. Static variables of each class, starting at the top of the inheriance hierarchy. 2. Member variables, starting at the top of the hierarchy. 3. Constructors, starting at the top of the hierarchy.
But consider the following example from Java-Certificate.com:
What is the output of the following program when you compile and execute it? Assume classes are defined in the same package.
1. Mobile.showDevice,Mobile.device Mobile.showDevice,Mobile.device Mobile.showDevice,Mobile.device 2. Phone.showDevice,Phone.device Mobile.showDevice,Mobile.device Mobile.showDevice,Mobile.device 3. Mobile.showDevice,null Mobile.showDevice,Mobile.device Mobile.showDevice,Mobile.device 4. Compile Time error 5. RunTimeException is thrown JavaCertificate.com says that Answer 3 is correct because
A new instance is created of the Mobile class, this class extends the Phone class. When the instance is created the Phone constructor is called, this constructor calls the showDevice() method, the showDevice() method of the Mobile class is called, this method is overridden in the Mobile class. This prints out "Mobile.showDevice,null", at the moment the showDevice() method is called the instance variables of the Mobile class are not yet initialized, the device variable is "null". After this the constructor of the Mobile class is called, once again the showDevice() method of the Mobile class is called. At this moment the device variable is initialized and will print out: Mobile.showDevice,Mobile.device. The main method calls the showDevice() method of the Mobile class and prints out: "Mobile.showDevice,Mobile.device". The complete output is: "Mobile.showDevice,nullMobile.showDevice,Mobile.device Mobile.showDevice,Mobile.device"
But if the member variables and static variables are initialized before the constructor, how can the method showDevice() return null?
I'm a bit puzzled with this one. Arthur. [ January 13, 2006: Message edited by: Arthur Blair ]
Compare the solution if Phone.showDevice() was renamed to Phone.showDevice2() and this call was replaced in the Phone constructor. Then it would output "Phone.showDevice,Phone.device" without a null.
Keep in mind java is a hierarchical structure and you have to take into account class order and inheritence. The first call to Mobile.showDevice() is invoked by the Phone constructor before the Mobile constructor has had a chance to initialize, therefore it has not violated any ordering problems. The second call to Mobile.showDevice() is invoked during the Mobile constructor where you are correct, the static/member variables are not available. [ January 13, 2006: Message edited by: Scott Selikoff ]
You've almost got it right, except 2 and 3 go together somewhat.
Static variables are initialized the first time you try to access them or instantiate a new class. And as you said, they start at the top of the hierarchy.
When you attempt to instantiate a class by calling one of its constructors, you first go to the constructor of the class you called. However, the first line of the constructor is super() unless you have written a call to super() or this() as the first line in your constructor.
So, we travel up the hierarchy all the way to Object with that implicit or explicit call to super() in the first line of each constructor we pass through.
The instance variables of Object will be initialized and its constructor will run and then return to the constructor it called. Upon returning, all instance variables will be initialized and then the rest of the constructor will run. So on and so forth until you return to the class of the object you created.
1. Static variables and blocks are initialized/run (Starting at top) 2. Constructor calls super() 2a. (#2 all the way up to Object) 3. Super instance variables and blocks are initialized/run 4. Superclass constructor code is run 4a. (#3 and #4 all the way back down) 5. Sub instance variables and blocks are initialized/run 6. Subclass constructor code is run