Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static keyword in Java

Tags:

java

class A {
    static {
        System.out.println("A-SIB");
    }
    static void test(){
        System.out.println("A-test");
    }
}

class B extends A  {
    static {
        System.out.println("B-SIB");
    }
}

class C  {
    public static void main(String args []){
        B.test();
    }
}

When I ran class C, I thought A-SIB, B-SIB and A-test will be printed, but B-SIB was not there in the output. Can somebody explain why?

like image 997
Aamir Avatar asked Mar 04 '14 17:03

Aamir


1 Answers

Here's what the JLS says about class initialization:

Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class.

Initialization of an interface consists of executing the initializers for fields (constants) declared in the interface.

Before a class is initialized, its direct superclass must be initialized, but interfaces implemented by the class are not initialized. Similarly, the superinterfaces of an interface are not initialized before the interface is initialized.

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.

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.

In this case, All you do in C with the class B is call the static method test(). But this method is declared in A, not in B. Thus, the JVM doesn't initialize the class B and thus doesn't invoke its static initializer block.

Note that the class B is referenced in C's byte-code and is loaded by the JVM. But it's not initialized. If you delete B.class and try to run C, you'll get an exception.

like image 53
JB Nizet Avatar answered Oct 06 '22 16:10

JB Nizet