The following Java code does not invoke the static initializer of class B
. Why?
Code:
class A
{
static
{
System.out.println("A static init");
}
public static void f()
{
System.out.println("f() called");
}
}
class B extends A
{
static
{
System.out.println("B static init");
}
}
public class App
{
public static void main( String[] args)
{
B.f(); //invokestatic #16 // Method com/db/test/B.f:()V
}
}
Program output:
A static init
f() called
Tested on JDK 1.8.0_25
Instance variables are initialized using initialization blocks. These blocks are executed when the class object is created and before the invocation of the class constructor. Also, it is not necessary to have initialization blocks in the class.
The static initializer is actually invoked later, when the class is initialized, after it has been loaded and linked. That happens when you instantiate an object of a class or access a static variable or method on the class.
No, we cannot override static methods because method overriding is based on dynamic binding at runtime and the static methods are bonded using static binding at compile time. So, we cannot override static methods.
Static initialzier blocks are not inherited . Static blocks are executed when class is loaded since your base class extends a super class , even the super class definition will be loaded by JVM when referring to your class. Lastly,the instance block can also never be inherited.
There is no such thing as "static constructor". It's a static initialization block, and it is only executed when the class is initialized. Since you are calling a static method of class A (even though you are referring to it via class B), there is no need to initialize class B. Calling B.f();
is the same as calling A.f();
.
The static initialization block of class B will be executed if you create an instance of class B or access a static member/method of class B.
Here are the only conditions that trigger class initialization (JLS 12.4.1):
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
T is a class and an instance of T is created. T is a class and a static method declared by T is invoked. A static field declared by T is assigned. A static field declared by T is used and the field is not a constant variable (§4.12.4). T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.
Since only class A
defines the method f(
), class B
is loaded but not initialized.
You could use java -verbose:class MyClassName
to check this.
On a jdk6 / jdk 8 machine, this will be printed.
[Loaded App from file:/C:/XXXX/]
[Loaded A from file:/C:/XXXXXX]
[Loaded B from file://C:/XXXXXXX]
A static init
f() called
Class B
will be initialized lazily but loaded greedily (since it is being referred).
Change your code to A.f()
. Then you will see that B
is not loaded.
[Loaded App from file:/C:/XXXX/]
[Loaded A from file:/C:/XXXXX]
A static init
f() called
Note : Class loading and initialization are 2 different things. Check documentation for Class.forName()
for details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With