Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Static Initialization Order [duplicate]

Tags:

I'm trying to discover the order in which initialization occurs, or rather the reason behind why initialization occurs in this order. Given the code:

public class Main {      {         System.out.printf("NON-STATIC BLOCK\n");     }      static{         System.out.printf("STATIC BLOCK\n");     }      public static Main m = new Main();      public Main(){         System.out.printf("MAIN CONSTRUCTOR\n");     }      public static void main(String... args) {         //Main m = new Main();         System.out.printf("MAIN METHOD\n");      } } 

Output:

STATIC BLOCK  NON-STATIC BLOCK  MAIN CONSTRUCTOR  MAIN METHOD 

However, moving m's declaration before the initialization block produces:

NON-STATIC BLOCK  MAIN CONSTRUCTOR  STATIC BLOCK  MAIN METHOD 

and I have absolutely no idea why it occurs in this order. Furthermore, if I eliminate the static keyword in the declaration of m, neither the init block nor the constructor fire. Can anyone help me out with this?

like image 804
jason todd Avatar asked Sep 27 '13 19:09

jason todd


People also ask

Can static variables be initialized twice?

It is allocated for the lifetime of program. Static functions can be called directly by using class name. Static variables are initialized only once.

In which order are initialization blocks run?

Initialization blocks run in the same order in which they appear in the program. Instance Initialization blocks are executed whenever the class is initialized and before constructors are invoked. They are typically placed above the constructors within braces.

How many static initializers can you have?

There can be multiple static initialization blocks in a class that is called in the order they appear in the program.

How do you initialize a static field in Java?

The only way to initialize static final variables other than the declaration statement is Static block. A static block is a block of code with a static keyword. In general, these are used to initialize the static members. JVM executes static blocks before the main method at the time of class loading.


1 Answers

I think you're just missing section 12.4.2 of the JLS, which includes:

Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

The "in textual order" part is the important bit.

If you change m from being static variable to an instance variable, then the field won't be initialized by class initialization - it'll only be initialized by instance initialization (i.e. when an instance is constructed). At the moment, that'll cause a stack overflow - creating one instance requires creating another instance, which requires creating another instance, etc.

EDIT: Similarly section 12.5 specifies instance initialization, including these steps:

  • Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5.

  • Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.

So that's why you're seeing "NON-STATIC BLOCK" before "MAIN CONSTRUCTOR".

like image 63
Jon Skeet Avatar answered Nov 24 '22 01:11

Jon Skeet