Do you really know instantiation?
To (re)discover some subtleties of this mechanism in Java...
This short post will show you which instructions are executed in your Java classes when you request an instance.
What will we test?
A Java class that you want to instantiate can have:
- one and only one
staticblock; - one and only one instance block (if you don’t know what that is, the example is coming up…);
- one or more constructors.
For completeness, a class can also contain the following, but this article does not cover their instantiation:
- one or more static nested classes;
- one or more inner classes.
The idea is to test the sequence of code lines during the instantiation mechanism, yet widely used by everyone!
The test setup
We have two classes at our disposal: Root and Child.
As their names indicate: Child inherits from Root, which is not always obvious when you implement the Hallyday interface (humour…).
For J-Jacques (still looking for an enum in this article) and Mika, here’s a small UML diagram:
You can hardly get simpler…
Here is the source code for the Root class:
public class Root {
// <1>
static {
System.out.printf("static block : %s %n", Root.class);
}
// <2>
{
System.out.printf("Root instance block : %s %n", this.getClass());
}
// <3>
public Root() {
System.out.println("Root noargs constructor");
}
}
We rarely get more concise, but this class is not trivial either, as it has:
- a static class block, triggered when the class is loaded by the ClassLoader, at its first call;
- an instance block, triggered before the class constructors;
- a no-arg constructor (no comment, I hope you know what a constructor is…)
And here is the source code for the Child class, implemented on the same principle as the Root class it inherits from.
public class Child extends Root {
static {
System.out.printf("static block : %s %n", Child.class);
}
{
System.out.printf("Child instance block : %s %n", this.getClass());
}
public Child() {
System.out.println("Child noargs constructor");
}
}
Only the different outputs change so we can differentiate the execution of each block.
At the result of instantiation
When we instantiate the class with the following code: Child child = new Child(), here is the result:
static block : class fr.fxjavadevblog.articles.Root
static block : class fr.fxjavadevblog.articles.Child
Root instance block : class fr.fxjavadevblog.articles.Child
Root noargs constructor
Child instance block : class fr.fxjavadevblog.articles.Child
Child noargs constructor
Comments:
- without surprise, the
staticblock ofRootexecutes first. - then comes the
staticblock ofChild: nothing surprising so far. - then it’s the instance block of
Rootwhilethis.getClass()returnsChild. Yes! The current concrete instance is indeed of typeChildeven though the code is in theRootclass. - the no-arg constructor of
Rootis triggered. Interesting, we still haven’t reached the instance block ofChild. For reference, the default constructor of a parent class is always called implicitly when no othersuper(args...)constructor is invoked explicitly. - here it is now, our instance block of
Child, interleaved between the no-arg constructor ofRootand its own constructor. - Finally, to close the sequence, the no-arg constructor of
Childbrings up the rear… It was about time!
“Etonnant non” ? Pierre Desproges, Dix minutes nécessaires de M. Cyclopède.


Comments