2

I have been looking at: https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom to understand a little bit more about Singletons.

My question is when exactly does the static inner class get Loaded and when does it get Initialised? My understanding is that classes can be loaded but remain uninitialised until initialisation is absolutely necessary.

If the class is not loaded, how is the private static inner class specified within the JVM?

1 Answers1

3

The exact time when a class is initialized, is specified in the Java® Language Specification, §12.4.1

§12.4.1. When Initialization Occurs

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.
  • 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 (§7.6) and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

When a class is initialized, its superclasses are initialized (if they have not been previously initialized), as well as any superinterfaces (§8.1.5) that declare any default methods (§9.4.3) (if they have not been previously initialized). Initialization of an interface does not, of itself, cause initialization of any of its superinterfaces.

The last bullet has been removed in Java 9

The time of class loading is not that fixed and may depend on implementation details, e.g. how the verifier has been implemented. But obviously, it has to happen before the initialization.

From the JVM’s point of view, the fact that this is a nested class has no special relevance. There is a symbolic reference to the inner class in the outer class’ constant pool, like there is for any other referenced class. It will be resolved when needed.

Community
  • 1
  • 1
Holger
  • 285,553
  • 42
  • 434
  • 765
  • Thanks so much! A few follow up questions. You mention that loading is dependent on implementation. What implementation exactly? Is the class loading determined in the Class Loaders? I’ve been reading that some class loader implementations load classes eagerly whereas some do not. Do you know what the Hotspot VM or the OpenJDK VM’s do? Secondly is there any distinguish when a class was loaded whereas when it was initialised? I ask because the article I linked says that the described idiom will work with any implementation but I am not too sure because as you describe it might be VM dependent. – pranavmalhotra May 15 '18 at 20:36
  • To clarify what I mean by ‘Is the class loading determined in the Class Loader’: I mean when the class loader loads a class, does it see a class (through a symbolic reference) that it has never seen before and try and load it or is the decision to load a class made in the execution engine when it is actually necessary? – pranavmalhotra May 15 '18 at 20:40
  • 1
    The most important thing first, the described idiom is compatible with all JVMs, as it only relies on the precisely specified initialization order, the loading time doesn’t matter. The loading time may make a difference if the existence of the class file changes, i.e. if you are deleting or creating class files concurrently. For normal programs, it should not matter. The class loader implementations normally have no influence, as all they do is locating and reading the class file bytes and passing them to one of the `defineClass` methods. From there, the JVM implementation takes over. – Holger May 16 '18 at 06:12