简体   繁体   中英

Creating an object of a class in its own static initializer

As per JLS :

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.

Also it says,

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

I infer two points from this

  • Class initialization consists of executing its static initializers
  • Class initialization happens if a class is instantiated .

Now,

I assume when I create an object of a class Test in its own (Test's own) static initializer it should throw me a stack overflow as it should call itself repeatedly because as per the above two points, instantiation of the class should initialize the class and initialization block has the instantiation of the class. A stack overflow occurs when I instantiate the class in its own constructor or in its own instance initializers.

For example,

public class Test {

    static{
        System.out.println("static test");
        new Test();
    }
    {
       //new Test(); // This will give a stack overflow
        System.out.println("intializer");
    }

    public Test(){
        //new Test(); // This will give a stack overflow
        System.out.println("constructor");
    }
    public static void main(String[] args) {
    }

}

However the result is something different.

Result:

static test intializer constructor

Either I am too confused understanding the initialization of the class or I do apologize if I am missing something very obvious here and appreciate your help.

Step 3 of the class initialization procedure, specified in JLS section 12.4.2 , is

If the Class object for C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.

Creating an instance of a class in its static initializer doesn't recursively reinitialize the class; recursive requests for initialization are detected and don't do anything.

(Note that "complete normally" means "the operation is done", not "follow the steps that would normally be followed to complete the operation"; it's opposite to "complete abruptly", which would mean we got some kind of exception or error.)

The static initializer only gets called when the class is loaded. Instantiating an object in the static initializer isn't going to result in the class getting loaded again, classloading of a class only happens once, the classloader caches the class for the life of the JVM instance.

If you created a new instance in the instance initializer or in the constructor then you'd get the stackoverflow error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM