Basic steps

Class loading is divided into the following five steps:

  • Load: find the corresponding class file according to the search path and import
  • Check: Check the correctness of the loaded class file
  • Preparation: Allocate memory space for static variables in a class
  • Resolution: The process by which the virtual machine replaces symbolic references in a constant pool with direct references. A symbolic reference is understood as an identity, while a direct reference points directly to an address in memory
  • Initialization: Performs initialization on static variables and static code blocks

The loading process

public class ClassLoadTest {
    public static int k = 0;
    public static ClassLoadTest t1 = new ClassLoadTest("t1");
    public static ClassLoadTest t2 = new ClassLoadTest("t2");
    public static int i = print("i");
    public static int n = 99;
    public int j = print("j");
    {
        print("Building block");
    }
    static {
        print("Static block");
    }
    public ClassLoadTest(String str) {
        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
        ++n;
        ++i;
    }
    public static int print(String str) {
        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
        ++n;
        return ++i;
    }
    public static void main(String[] args) {
        new ClassLoadTest("ClassLoadTest"); }}Copy the code

print

1:j   i=0   n=0
2: constructor block I =1   n=1
3:t1    i=2  n=2
4:j   i=3   n=3
5: constructor block I =4   n=4
6:t2    i=5  n=5
7:i   i=6   n=6
8: Static block I =7   n=99
9:j   i=8   n=100
10: constructor block I =9   n=101
11:ClassLoadTest    i=10  n=102  
Copy the code

The sample analysis

  • To execute main, load the class, declare static variables, and initialize static variables to execute static code blocks (in order)
  • At this point, k=0, while I and n are not initialized, the default value of the system is 0. When j is initialized, k increases to 1, I and n are 0, and the output “1:j I =0, n=0”, n and I increase to 1, execute the code block, Execute the constructor and print “3:t1 I =2 n=2”, n, I increment to 3
  • At this point, k=3, I, n are not initialized, but have been incremented to 3. When j is initialized, k increases to 4, I, n is not initialized to 3. Output “4:j I =3 n=3”, n, I increase to 4. Execute the constructor and print “6:t2 I =5 n=5”, n, I increment to 6
  • Initialize I, output “7: I I =6 n=6”, n, I increment to 7, return the value of I assigned to I
  • Initialize n and assign 99
  • Run the static block command and output “8: static block I =7 n=99”. The value of I increases to 8 and the value of n increases to 100

Class loading process

When loading a class, you declare a static member variable, initialize it to its default value, and then initialize the static member variable. Execute a static code block. Execute a static code block.

If the class instantiation process is invoked during a class loading process (for example, a new class object is created), the system suspends the class loading process to execute the instantiation process and then returns to the class loading process

Instantiation process

Before instantiating a class, instantiate its parent class. When instantiating a class, you first declare member variables, initialize them to default values, and then initialize the member variables. Code blocks are executed sequentially

Active and passive use of classes

  1. Active use scenario
    • The most commonly used new instance object of a class
    • Call the static method of the class directly
    • Operates on non-compile-time constant static fields declared in the class or interface
    • Reflection calls a method of a class
    • When you initialize a subclass of a class, the parent class is also called by the program. (If the static variable of the calling subclass is inherited from the parent class and not overridden, then only the parent class is used, and the subclass does not need to be initialized at this time.)
    • Classes that directly run an entry to the main function

All JVM implementations load a class the first time it is actively used.

  1. Passive use scenario
    • A subclass calls a static variable of its parent class, and the subclass is not initialized. Only the parent class is initialized. For static fields, only the class that directly defines the field is initialized
    • Referencing a class through an array definition does not trigger class initialization, as inSubClass[] sca = new SubClass[10]
    • Access the compile-time constants of the class without initializing the class

Compile-time constant

  1. The types written to the class constant pool are limited: String and a few primitive types

    A String value of null is also written to the class constant pool when a new String(“xx”) is used to create a String that is not in the class constant pool

  2. When a string is generated from new (let’s say “China”), the constant pool looks to see if it already has a “China” object. If not, a copy of the “China” object is created in the constant pool, and a copy of the “China” object is created in the heap.

Variable initialization

  1. Normal member variables can be initialized at declaration time, in code blocks, or in constructors
  2. Static variables can be initialized in a static block at declaration time
  3. Member variables have default initial values
byte:0(8A)short:0(16A)int:0(32A)long:0L(64A)char:\u0000(16Bit), representing NULLfloat:0.0 F(32A)double:0.0(64A)boolean: flase
Copy the code
  1. After local variables are declared, the Java virtual machine does not automatically initialize to default values

Therefore, local variables must be initialized by display before they can be used. If the compiler confirms that a local variable may not have been initialized before use, the compiler will report an error

Class loader

classification

graph TB
	B(Bootstrap ClassLoader)-->E(ExtensionClassLoder)
	E-->S(Application ClassLoader)
	S-->U(User-Defined ClassLoder)
  1. Bootstrap classLoader (jre\lib\rt.jar includes core libraries such as java.lang)

    When running the Java virtual machine, this class loader is created, which loads some basic Java apis, including the Object class. Note that this class loader is implemented in C/C++

  2. Extension Class loader (jre\lib\ext\ *.jar)

    The loader loads extended classes beyond the base API, including security-related classes

  3. Application ClassLoader (specified by classpath)

    It loads the classes in the application, that is, the classes configured in the classpath

  4. User-Defined ClassLoader

    Developers load classes defined by programmers by extending a custom loader defined by the ClassLoader class

function

  1. It is responsible for loading bytecode files, the class file is marked at the beginning of the file, and the ClassLoader is responsible for loading the class file. It is up to the Execution Engine to determine whether or not it can run

  2. The main function

    • Locate and import binary class files

    • Verify the correctness of the imported class

    • Allocate initialization memory for classes

    • Helps resolve symbolic references

Delegate pattern

  1. Bottom-up detection to see if classes have been loaded

    When the JVM loads a class, the lower loader delegates the task to the upper loader, which checks to see if the class is already loaded in its namespace, and if so, uses the class directly. If not loaded, continue delegating up to the top level

  2. Try loading the class from the top down

    If the class is not loaded, the Bootstrap loader loads the class in the reverse order. If the Bootstrap loader cannot find the class, it delegates down until the class file is found. For a particular classLoader, a Java class can only be loaded once, which means that in the Java virtual machine, the full identification of the class is (classLoader, package, className).

    The uniqueness of any class in Java is determined by the class itself and the class loader that loads the class

  3. advantages

    Make the class has the hierarchy division. In the case of java.lang.Object, the Bootstrap ClassLoader finds the java.lang.Object in the Rt. jar in jre\lib and loads it into the JVM. If a rogue builds a java.lang.Object with bad code embedded in it and implements it according to the parent delegate model, the only thing that ends up being loaded into the JVM is what’s inside the Rt.jar, which means that the core base class code is protected