Behavior of static blocks with inheritance

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?


Solution 1:

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.

Solution 2:

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.

Solution 3:

There is a single copy of myVar and both parent and child class will share the same. Untill and unless child class get initilized.

Solution 4:

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..!!