I'd like to post some Java code illustrating how static initialization blocks, constructors and the finalize() method are used. These examples should be common knowledge for any experienced Java developer. First here are the two classes I've created to demonstrate:
Class: Guitar
package com.anthonychaves.scratch;
public class Guitar {
int numStrings = 6;
static final String nameBrand = "Fender";
static {
System.out.println("This is the com.anthonychaves.scratch.Guitar static initializer.");
}
public Guitar() {
System.out.println("This is the com.anthonychaves.scratch.Guitar constructor.");
}
public void finalize() {
System.out.println("This is the com.anthonychaves.scratch.Guitar#finalize() method.");
}
}
Class: TwelveStringGuitar
package com.anthonychaves.scratch;
public class TwelveStringGuitar extends Guitar {
public TwelveStringGuitar() {
numStrings = 12;
//nameBrand = "Celebrity"; // I can't do this because nameBrand is final
nameBrand.replaceAll("Fender", "Celebrity"); // so I have to do this instead.
System.out.println("This is the com.anthonychaves.scratch.TwelveStringGuitar constructor.");
}
public static void main(String args[]) throws Exception {
Guitar anthonysGuitar;
System.out.println("Static initializer should have been called.");
Guitar mikesGuitar = new TwelveStringGuitar();
anthonysGuitar = new TwelveStringGuitar();
mikesGuitar = new Guitar();
Thread.sleep(10000);
System.gc();
Thread.sleep(10000);
System.out.println("End of main.");
}
}
The main entry point into this code is in the
TwelveStringGuitar#main(String)
method. The first thing it does is declare anthonysGuitar of type Guitar. When this happens the Guitar class is loaded into the JVM and the static initializer block is called at load time, not when an object of type Guitar is instantiated. Because of this restriction only static class variables are accessable within a static initialization block. An object of type Guitar does not exist yet and therefore the numStrings variable can not be used in that static block.
The second thing to point out is that an object always calls the constructor of its parent class, explicitly or not, preceeding any other lines of code. The
TwelveStringGuitar
constructor does not have a line that says
super()
but the Guitar() constructor is called anyway. If you were to compile and run these classes the line This is the com.anthonychaves.scratch.Guitar constructor will always be called before This is the com.anthonychaves.scratch.TwelveStringGuitar constructor.
The last thing to point out in this code is the use of the
finalize()
method. This method is inherited from Object and is called by the JVM when the garbage collector is about to destroy the instance of the class. In the example mikesGuitar is shown to first be a TwelveStringGuitar and later a regular Guitar. After the line
mikesGuitar = new Guitar();
the previous TwelveStringGuitar object mikesGuitar referred to is sitting in the heap with zero references to it. Because of this, and requesting the garbage collector be run by calling System.gc(), that TwelveStringGuitar object can be destroyed. Before it is destroyed the JVM calls finalize(), which TwelveStringGuitar inherits from Guitar, and the notice This is the com.anthonychaves.scratch.Guitar#finalize() method is printed to the console.
I chose to use the keyword final and the finalize() method in this example to show how they are in no way related to one another. The keyword finally is also not related to either final or finalize(), only used as a “no matter what do this step last” clause in a try block.
That's all for this quick demonstration. As always comments are welcome.




