Let express with a more clear example:
public class Test {
static {
System.out.println("static initializer");
}
{
System.out.println("instance initializer");
}
public Test() {
System.out.println("constructor");
}
}
and test it as follows:
public class Main {
public static void main(String[] args) {
Test test1 = new Test();
Test test2 = new Test();
}
}
output:
static initializer
instance initializer
constructor
instance initializer
constructor
The static initializers are executed only once during runtime, specifically during loading of the class. The instance initializers are executed during every instantiation before the constructor.
You can have more than one of them and they will be executed in the order as they appear in the coding.
The major benefit of instance initializers is that they are executed regardless of which constructor you use. They applies on each of them so that you don't need to duplicate common initialization over all of them.
The major benefit of static initializers is that they are executed only once during class loading. A well known real world example is the JDBC driver. When you do
Class.forName("com.example.jdbc.Driver");
which only executes the static
initializers, then any (decent) JDBC driver will register itself in the DriverManager
as follows
static {
DriverManager.registerDriver(new com.example.jdbc.Driver());
}
this way the DriverManager
can find the right JDBC driver during getConnection()
.