I am trying to use static blocks like this:
I have a base class called Base.java
public class Base {
static public int myVar;
}
And a derived class Derived.java
:
public class Derived extends Base {
static
{
Base.myVar = 10;
}
}
My main
function is like this:
public static void main(String[] args) {
System.out.println(Derived.myVar);
System.out.println(Base.myVar);
}
This prints the out put as 0 0
where as I expected 10 0
. Can somebody explain this behavior? Also, if I want my derived classes to set the values for a static variable how can I achieve that?
As I understand. You don't call any Derived
properties (myVar
belongs to Base
, not to Derived
). And java is not running static block from Derived
. If you add some static field to Derived
and access it, then java executes all static blocks.
class Base {
static public int myVar;
}
class Derived extends Base {
static public int myVar2;
static
{
Base.myVar = 10;
}
}
public class Main {
public static void main( String[] args ) throws Exception {
System.out.println(Derived.myVar2);
System.out.println(Base.myVar);
}
}
From java specification, when class is initialized (and static block got executed):
12.4.1 When Initialization Occurs 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.
Static initializer-blocks aren't run until the class is initialized. See Java Language Specification paragraphs 8.7 (Static initializers) and 12.4.1 (When initialization occurs):
A static initializer declared in a class is executed when the class is
initialized (§12.4.2). Together with any field initializers for class
variables (§8.3.2), static initializers may be used to initialize the
class variables of the class.
Here's a similar example straight out of JLS 12.4.1:
class Super {
static int taxi = 1729;
}
class Sub extends Super {
static { System.out.print("Sub "); }
}
class Test {
public static void main(String[] args) {
System.out.println(Sub.taxi);
}
}
This program prints only:
1729
because the class Sub is never initialized; the reference to Sub.taxi
is a reference to a field actually declared in class Super and does
not trigger initialization of the class Sub.
There is a single copy of myVar
and both parent and child class will share the same.
Untill and unless child class get initilized.
Here is the link to the Java Specification - section 8.7 talks about static initializers. It gives good details about how they should function and the order in which they get called. http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.7
When we do
class Base {
public static int myVar = 0;
static {
System.out.println("Base");
}
}
class Derived extends Base {
static {
System.out.println("Derived");
Base.myVar = 9;
}
}
public class StaticBlock {
public static void main(String[] args) {
System.out.println(Base.myVar);
System.out.println(Derived.myVar);
}
}
The Output will be
Base
0
0
That means derived class's static block not executing..!!