In What Order Are Static Blocks and Static Variables in a Class Executed

in what order are static blocks and static variables in a class executed?

From section 12.4.2 of the JLS, snipped appropriately:

The procedure for initializing C is then as follows:

  • Then, initialize the final class variables and fields of interfaces whose values are compile-time constant expressions (§8.3.2.1, §9.3.1, §13.4.9, §15.28).

  • 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.

So for non-compile-time-constants, it's not a case of "all variables" and then "all static initializers" or vice versa - it's all of them together, in textual order. So if you had:

static int x = method("x");

static {
System.out.println("init 1");
}

static int y = method("y");

static {
System.out.println("init 2");
}

static int method(String name) {
System.out.println(name);
return 0;
}

Then the output would be:

x
init 1
y
init 2

Even making x or y final wouldn't affect this here, as they still wouldn't be compile-time constants.

P.S:Also noticed that string variable initialization happens before the block only when i insert the final modifier.

At that point, it's a compile-time constant, and any uses of it basically inlined. Additionally, the variable value is assigned before the rest of the initializers, as above.

Section 15.28 of the JLS defines compile-time constants - it includes all primitive values and String, but not the wrapper types such as Integer.

How the order of execution is performed between static variables and blocks?

From the Java Language Specification §8.3.2.3

The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:

  • The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
  • The usage is not on the left hand side of an assignment.
  • The usage is via a simple name.
  • C is the innermost class or interface enclosing the usage.

It is a compile-time error if any of the four requirements above are not met.

[...]

The restrictions above are designed to catch, at compile time, circular or otherwise malformed initializations

In other words, it's OK to write to a field that is declared later in the class, but not to read from it.

There are more detailed examples of this in the example box immediately following the section I have quoted.

Why are static blocks/static variables in super class initialized before main?

static initializer blocks are called when the class loader loads a class. In a nutshell, the order of execution here is as follows:

  1. Attempt to load test, see it depends on sub
  2. Attempt to load sub, see it depends on sup
  3. Attempt to load sup
  4. sup is loaded, and its static block prints "In Sup"
  5. sub's loading is resumed, and its static block prints "In Sub"
  6. test's loading is resumed, and a is initialized to 10.
  7. test's static block is executed and prints " In test10"
  8. test's main function is executed, and does nothing, since it's empty.

In what order do static/instance initializer blocks in Java run?

The static initializer for a class gets run when the class is first accessed, either to create an instance, or to access a static method or field.

So, for multiple classes, this totally depends on the code that's run to cause those classes to get loaded.

Order of static initialization blocks

Static initializers are executed as soon as the class is loaded. The main method is called after the class has been loaded.

This section of the JLS discusses the sequence of events (12.1.3-4):

12.1.3. Initialize Test: Execute Initializers


In our continuing example, the Java Virtual Machine is still trying to execute the method main of class Test. This is permitted only if the class has been initialized (§12.4.1).

Initialization consists of execution of any class variable initializers and static initializers of the class Test, in textual order. But before Test can be initialized, its direct superclass must be initialized, as well as the direct superclass of its direct superclass, and so on, recursively. In the simplest case, Test has Object as its implicit direct superclass; if class Object has not yet been initialized, then it must be initialized before Test is initialized. Class Object has no superclass, so the recursion terminates here.


12.1.4. Invoke Test.main


Finally, after completion of the initialization for class Test (during which other consequential loading, linking, and initializing may have occurred), the method main of Test is invoked.

Order of static variable initialization, Java

They are executed in the order that you write them. If the code is:

public class Test {

static int k = 1;
static {k = 2;}

public static void main(String[] args) {
System.out.println(k);
}

}

then the output becomes 2.

The order of initialization is: ..the class variable initializers and static initializers of the class..., in textual order, as though they were a single block.

And the values (for your code) are: k = 0 (default), then it's set to 2, then it's set back to 1.

You can check that it's actually set to 2 by running the following code:

private static class Test {

static {
System.out.println(Test.k);
k = 2;
System.out.println(Test.k);
}
static int k = 1;

public static void main(String[] args) {
System.out.println(k);
}
}


Related Topics



Leave a reply



Submit