Search code examples
javajvmclassloader

Does Java Class Linkage Resolution step OR Initialisation lead to loading of other resolved classes?


I was going through the JVM specification document and JLS , on the classloading mechanism in java .

Here is what I understand .

  1. At first the when the main class is being asked to be loaded , it looks if the binary representation of the class has been already loaded or not , if not the class loader loads the class file from the disk .

  2. Linkage Steps: Verification ,Preparation and Resolution

  3. Initialisation.

    Loading and linking steps.

What I find confounding is , while in the Resolution and Initialisation steps if a class is referenced which has yet not been loaded from the source , what happens ? does the Resolution or Initialisation step pause for the Classloading to happen by it's parent classloader?

Or is the loading , Linking and Initialization deferred till the time actual method or code using that reference is executed at runtime ?


Solution

  • JVMS §5.4. Linking states:

    Linking a class or interface involves verifying and preparing that class or interface, its direct superclass, its direct superinterfaces, and its element type (if it is an array type), if necessary. Resolution of symbolic references in the class or interface is an optional part of linking.

    So when not talking about the direct supertypes of a class, the resolution is optional and may be deferred.

    The same section also contains

    For example, a Java Virtual Machine implementation may choose to resolve each symbolic reference in a class or interface individually when it is used ("lazy" or "late" resolution), or to resolve them all at once when the class is being verified ("eager" or "static" resolution). This means that the resolution process may continue, in some implementations, after a class or interface has been initialized.

    So the process does not always strictly follow the graphic you’ve shown in the question. Instead, the resolution can be seen as an ongoing process.

    In practice, in case of the HotSpot JVM, some classes have to get resolved immediately, like the superclasses. Other classes are resolved when verifying code of a method, which happens right before the first execution of a method for this JVM.

    This does not affect all classes referenced by a method’s code but depend on the actual type use, e.g. HotSpot’s verifier will resolve types for checking the validity of assignments against the actual type hierarchy, but skip this step, if a type is assigned to itself or to java.lang.Object, i.e. where the assignment is always valid. So some types may get resolved only at their first actual use, e.g. when they are instantiated via new or a static method declared by the type is invoked. But this depends on subtle aspects of the code. See also When is a Java Class loaded? or Does the JVM throw if an unused class is absent?

    There might be types referenced only in reflective data like annotations or debug attributes which get never resolved during a run, but may be in another.

    But since this implies that the resolution of a type is deferred to the point when it is actually needed, it also implies that right at this point, the operation will stop and wait for the completion of this process for the prerequisite classes. So, e.g. loading a class always implies resolving its direct superclass, loading it if not already loaded, which in turn implies resolving of the superclass of the superclass and so on. So it won’t return before the complete super class hierarchy has been resolved.