public class Main {
public static void main(String[] args) {
System.out.println(B.x);
}
}
class A {
public static String x = "x";
}
class B extends A {
static {
System.out.print("Inside B.");
}
}
Question: Why output will be: x
. But not: Inside B.x
No,They never participates in inheritance. because staticblock is used for initializing static data member similarly instance is for initializing instance datamembers. Static block in java is executed before main method. If we declare a Static block in java class it is executed when class loads.
A Static Initialization Block in Java is a block that runs before the main( ) method in Java. Java does not care if this block is written after the main( ) method or before the main( ) method, it will be executed before the main method( ) regardless.
One can not override a static block as the non-static else compile-time error will be generated. Non-static block can not be overridden as a static block.
Static methods in Java are inherited, but can not be overridden. If you declare the same method in a subclass, you hide the superclass method instead of overriding it. Static methods are not polymorphic. At the compile time, the static method will be statically linked.
The reference to B.x
issues the following bytecode:
getstatic #3 <Field int B.x>
According to Java Virtual Machine Spec
The Java virtual machine instructions anewarray, checkcast, getfield, getstatic, instanceof, invokedynamic, invokeinterface, invokespecial, invokestatic, invokevirtual, ldc, ldc_w, multianewarray, new, putfield, and putstatic make symbolic references to the runtime constant pool. Execution of any of these instructions requires resolution of its symbolic reference.
So the JVM should resolve the symbolic reference to B.x
. The field resolution is specified like this:
To resolve an unresolved symbolic reference from D to a field in a class or interface C, the symbolic reference to C given by the field reference must first be resolved (§5.4.3.1).
...
When resolving a field reference, field resolution first attempts to look up the referenced field in C and its superclasses:
If C declares a field with the name and descriptor specified by the field reference, field lookup succeeds. The declared field is the result of the field lookup.
Otherwise, field lookup is applied recursively to the direct superinterfaces of the specified class or interface C.
Otherwise, if C has a superclass S, field lookup is applied recursively to S.
Otherwise, field lookup fails.
In other words the JVM will resolve B.x
into A.x
. This is why only A
class needs to be loaded.
Because B.x
is actually A.x
so only the A
class needs to be loaded.
§12.4 "Initialization of Classes and Interfaces" of The Java Language Specification, Java SE 7 Edition specifies that:
Initialization of a class consists of executing its
static
initializers and the initializers for static fields (class variables) declared in the class.[…]
A reference to a
static
field (§8.3.1.1) causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.
So although — contrary to claims in some of the answers above — class B
does have to be loaded, in order to determine that B.x
is declared in A
, class B
is not initialized (i.e., its static
initializers are not actually run) until you do something more specific to B
.
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