When Does Static Class Initialization Happen

When does static class initialization happen?

A class's static initialization normally happens immediately before the first time one of the following events occur:

  • an instance of the class is created,
  • a static method of the class is invoked,
  • a static field of the class is assigned,
  • a non-constant static field is used, or
  • for a top-level class, an assert statement lexically nested within the class is executed1.

See JLS 12.4.1.

It is also possible to force a class to initialize (if it hasn't already initialized) by using Class.forName(fqn, true, classLoader) or the short form Class.forName(fqn)



When does static class initialization happen?

See above.

When are static fields initialized?

As part of static class initialization; see above.

If I never instantiate a class, but I access a static field, are ALL the static blocks and private static methods used to instantiate private static fields called (in order) at that instant?

Yes. (Modulo that nothing is truly instantaneous.)

What if I call a static method? Does it also run all the static blocks? Before the method?

Yes and yes.


Note that it is possible to construct code where you can observe the default initialized value of a static field.


1 - The final bullet point was present in the JLS for Java 6 through Java 8, but it was apparently a mistake in the specification. It was finally corrected in the Java 9 JLS: see source.

When are static variables initialized?

From See Java Static Variable Methods:

  • It is a variable which belongs to the class and not to object(instance)
  • Static variables are initialized only once , at the start of the execution. These variables will be initialized first, before the initialization of any instance variables
  • A single copy to be shared by all instances of the class
  • A static variable can be accessed directly by the class name and doesn’t need any object.

Instance and class (static) variables are automatically initialized to standard default values if you fail to purposely initialize them. Although local variables are not automatically initialized, you cannot compile a program that fails to either initialize a local variable or assign a value to that local variable before it is used.

What the compiler actually does is to internally produce a single class initialization routine that combines all the static variable initializers and all of the static initializer blocks of code, in the order that they appear in the class declaration. This single initialization procedure is run automatically, one time only, when the class is first loaded.

In case of inner classes, they can not have static fields

An inner class is a nested class that is not explicitly or implicitly
declared static.

...

Inner classes may not declare static initializers (§8.7) or member interfaces...

Inner classes may not declare static members, unless they are constant variables...

See JLS 8.1.3 Inner Classes and Enclosing Instances

final fields in Java can be initialized separately from their declaration place this is however can not be applicable to static final fields. See the example below.

final class Demo
{
private final int x;
private static final int z; //must be initialized here.

static
{
z = 10; //It can be initialized here.
}

public Demo(int x)
{
this.x=x; //This is possible.
//z=15; compiler-error - can not assign a value to a final variable z
}
}

This is because there is just one copy of the static variables associated with the type, rather than one associated with each instance of the type as with instance variables and if we try to initialize z of type static final within the constructor, it will attempt to reinitialize the static final type field z because the constructor is run on each instantiation of the class that must not occur to static final fields.

When will a static class initialize?

The objects o1 and o2 are not available to your static context without making them static also.

JVMS states that

Any static initializers declared in a class are executed when the class is initialized

Further

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.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).
  • T is a top-level class, and an assert statement (§14.10) lexically nested within T is
    executed.

So in your case, when the static method compute() is first executed.

Is the order of static class initialization in C# deterministic?

Straight from ECMA-334:

17.4.5.1: "If a static constructor (§17.11) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class."

And:

17.11: The execution of a static constructor is triggered by the first
of the following events to occur within an application domain:

  • An instance of the class is created.
  • Any of the static members of the class are referenced.

If a class contains the Main method (§10.1) in which execution begins, the static constructor for that class
executes before the Main method is called. If a class contains any static fields with initializers, those
initializers are executed in textual order immediately prior to executing the static constructor (§17.4.5).

So the order is:

  • A.X used, so static A() called.
  • A.X needs to be initialized, but it uses B.X, so static B() called.
  • B.X needs to be initialized, and it is initialized to 7. B.X = 7
  • All static fields of B are initialized, so static B() is called. X is printed ("7"), then it is set to A.X. A has already started being initialized, so we get the value of A.X, which is the default value ("when a class is initialized, all static fields in that class are first initialized to their default value"); B.X = 0, and is printed ("0").
  • Done initializing B, and the value of A.X is set to B.X+1. A.X = 1.
  • All static fields of A are initialized, so static A() is called. A.X is printed ("1").
  • Back in Main, the values of A.X and B.X are printed ("1", "0").

It actually comments upon this in the standard:

17.4.5: It is possible for static fields with variable initializers to be observed in their default value state. However, this is strongly discouraged as a matter of style.

When are static C++ class members initialized?

The standard guarantees two things - that objects defined in the same translation unit (usually it means .cpp file) are initialized in order of their definitions (not declarations):

3.6.2

The storage for objects with static storage duration (basic.stc.static) shall be zero-initialized (dcl.init) before any other initialization takes place. Zero-initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization. Objects of POD types (basic.types) with static storage duration initialized with constant expressions (expr.const) shall be initialized before any dynamic initialization takes place. Objects with static storage duration defined in namespace scope in the same translation unit and dynamically initialized shall be initialized in the order in which their definition appears in the translation unit.

The other guaranteed thing is that initialization of static objects from a translation unit will be done before use of any object or function from this translation unit:

It is implementation-defined whether or not the dynamic initialization (dcl.init, class.static, class.ctor, class.expl.init) of an object of namespace scope is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first use of any function or object defined in the same translation unit as the object to be initialized.

Nothing else i guaranteed (especially order of initialization of objects defined in different translation units is implementation defined).

EDIT
As pointed in Suma's comment, it is also guaranteed that they are initialized before main is entered.

When is the static block of a class executed?

Yes, you are right. Static initialization blocks are run when the JVM (class loader - to be specific) loads StaticClass (which occurs the first time it is referenced in code).

You could force this method to be invoked by explicitly calling StaticClass.init() which is preferable to relying on the JVM.

You could also try using Class.forName(String) to force the JVM to load the class and invoke its static blocks.



Related Topics



Leave a reply



Submit