35

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?

Asha
  • 11,002
  • 6
  • 44
  • 66
  • Because class is not initialised, so that static block is not initialised. but you uncomment (new Derived() )it will print 10,10, But it will never print 10,0 – Guest Nov 29 '16 at 20:09

5 Answers5

24

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.

maba
  • 47,113
  • 10
  • 108
  • 118
Mikita Belahlazau
  • 15,326
  • 2
  • 38
  • 43
6

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.

esaj
  • 15,875
  • 5
  • 38
  • 52
  • 2
    @NikitaBeloglazov: In your example, the static-block works, because the top-level class Base is initialized when Derived is referenced. See JLS "12.4.1 When Initialization Occurs" for details, the initialization procedure is quite complicated: `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.` – esaj May 22 '12 at 09:05
  • 2
    Yes, you are right. But your example may be confusing, because it looks like class initialized only when instance of the class is created. – Mikita Belahlazau May 22 '12 at 09:07
  • @NikitaBeloglazov: True, I'd better edit out my own example and just refer to the one in JLS to avoid confusion. – esaj May 22 '12 at 09:08
  • So I have to call new to initialize the sub-class then? – JohnyTex Nov 07 '18 at 09:07
1

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

BOSS
  • 2,931
  • 8
  • 28
  • 53
1

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

Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
J.K
  • 2,290
  • 1
  • 18
  • 29
0

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

Johnnie
  • 305
  • 2
  • 16