3

Understanding about loading a class and calling static initializer

In what order do static initializer blocks

So, I just tried to confirm it -

public class OOMErrorB extends OOMErrorA {
    public static int c = 10;

    static {
        System.out.println("Loading static B " + c);
        System.out.println(OOMErrorA.a);
    }

    public static void main(String[] args) {
        new OOMErrorB();
    }
}

The parent class is -

public class OOMErrorA {
    public static int a = 20;

    static {
        a = a+ OOMErrorB.c;
        System.out.println("OOMErrorB.c " + OOMErrorB.c);
        System.out.println("loading OOMErrorA.a " + a);
    }
}

Now Output of main method of B -

**

OOMErrorB.c 0
loading OOMErrorA.a 20
Loading static B 10
20

**

I can understand that first it is loading class A because it's Super class and calling it's static initializers,

now since i am accessing OOMErrorB.c in static block of OOMErrorA , it should load and call static initializer of OOMErrorB. so, OOMErrorB.c should be 10 and not 0 .

What i know about loading and initializing of a class -

1) Class and gets loaded and variables are initialized to default values like for int - 0, Object - null.
2) Class field are initialized to specified values.
3) Static block gets called .

here in my program , i can see that class OOMErrorB got loaded (step 1) , but step 2 and step 3 didn't execute.

whereas according to accepted answer on link, it should call static initializer of OOMErrorB.

so it should end up in a cyclic dependency ?

Community
  • 1
  • 1
Adon Smith
  • 1,849
  • 7
  • 19
  • 19

1 Answers1

1

When accessing OOMErrorB.c, OOMErrorB is not loaded because it is already in the process of being loaded (when the JVM initially loaded it in order to invoke the main method). Once a class is loaded in the JVM, it will not be loaded again. Therefore, no cyclic dependency occurs: OOMErrorB's static member c is fetched, which at this moment is still not initialized.

You can check this section from the Java language specification about class initialization:

Because the Java programming language is multithreaded, initialization of a class or interface requires careful synchronization, since some other thread may be trying to initialize the same class or interface at the same time. There is also the possibility that initialization of a class or interface may be requested recursively as part of the initialization of that class or interface; for example, a variable initializer in class A might invoke a method of an unrelated class B, which might in turn invoke a method of class A. The implementation of the Java Virtual Machine is responsible for taking care of synchronization and recursive initialization by using the following procedure.

The JVM has its proper way of locking the initialization of classes so that recursive initialization is prevented.

M A
  • 71,713
  • 13
  • 134
  • 174
  • the program has not yet entered in main method , we can print a statement there and see . – Adon Smith May 09 '15 at 16:57
  • Oh i think i got the point so JVM will work like this - 1) It will load class A (step 1) 2) then it will load class B (step 1) 3) it will call static of class A 4) it will call static of class B . – Adon Smith May 09 '15 at 17:00
  • @AdonSmith You're right. I meant it is loaded before the JVM invokes its `main`. – M A May 09 '15 at 17:00
  • do you agree with the steps i have mentioned ? – Adon Smith May 09 '15 at 17:02
  • @AdonSmith The exact steps are also mentioned in the provided link. See also http://stackoverflow.com/questions/19058766/java-static-initialization-order. – M A May 09 '15 at 17:10