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?
It is allocated for the lifetime of program. Static functions can be called directly by using class name. Static variables are initialized only once.
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.
There can be multiple static initialization blocks in a class that is called in the order they appear in the program.
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.
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".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With