[Java] class loading and object creation in java

JAVA class loading mechanism

Java class loading is divided into 5 processes, namely: loading, connection (verification, preparation, analysis), initialization, use, and unloading.

  1. Loading
    Loading is mainly to read .class files (or zip packages) into the JVM through a binary byte stream. In the loading phase, the JVM needs to complete 3 things:
    1) Obtain the XXX.class file from the classpath through the classloader, and read it into the memory in the form of a binary stream.
    2) Convert the static storage structure represented by the byte stream into the runtime data structure of the method area;
    3) Generate a java.lang.Class object of this class in the memory to access various data of this class in the method area Entrance.

2.1. Verification
Mainly to ensure that the loaded byte stream conforms to the JVM specification. The verification phase will complete the following 4 phases of inspection actions:
1) File format verification
2) Metadata verification (whether it conforms to the Java language specification)
3) Bytecode verification (determine the program semantics are legal and logical)
4) Symbol reference verification ( (Ensure that the next analysis can be executed normally)
2.2. Preparation
Preparation is the second step of the connection phase, which mainly allocates memory for static variables in the method area and sets the default initial value.
2.3. Resolution
Resolution is the third step of the connection phase, which is the process in which the virtual machine replaces the symbol references in the constant pool with direct references.

  1. Initialization The
    initialization phase is the last step of the class loading process, which is mainly to actively assign values ​​to class variables according to the assignment statements in the program.
    When there is an inheritance relationship, the parent class is initialized first and then the child class is initialized, so when a child class is created, there are actually two object instances in the memory.
    Note: If the inheritance relationship of the class is too long, considering the class initialization alone, this design is not preferable. I think you have guessed the reason.
    It is generally recommended that the class inheritance relationship does not exceed three levels at most, namely parent-child-grandchild. In some special application scenarios, layer 4 may be added, but stop there, layer 4 already has code design flaws.
  2. Use
    mutual calls between programs.
  3. Unloading
    means destroying an object, which is usually done by the JVM garbage collector. Destruction at the code level just sets the reference to null.

After passing the above overall introduction, let's look at the execution analysis of Singleton2.getInstance():
1) Class loading. Run Singleton2.getInstance(), JVM did not find the related information of Singleton class for the first time. So the Singleton.class file is loaded into the memory through the classloader.
2) Class verification.
3) Preparation for class is omitted . Convert the static resources in Singleton2 to the method area. Value1, value2, and singleton are initially declared as 0, 0, and null in the method area.
4) Class analysis. Omit (the process of replacing the symbol references in the constant pool with direct references)
5) Initialization of the class. Perform the assignment of static properties. First order value1 = 5, value2 = 3, followed by private static Singleton2 singleton2 = new Singleton2 ( );
this operation is to create objects, according to conclusions 1 prior to performing the constructor Singleton2, go to perform static and non-static resource resources . But since value1 and value2 have been initialized, the next execution is the non-static resource, and finally the construction method of Singleton2: value1++; value2++.
So Singleton2 results in 6 and 4.

In addition to clarifying the execution order, there is another important point -> Conclusion 2: Static resources will only be executed once in the initialization of the class . Not to be confused with the third step.

With the above conclusion, let's look at the execution analysis of Singleton.getInstance():
1) Class loading. Load the Singleton class into memory.
2) Class verification.
3) Preparation for class is omitted . Convert the static resources of Singleton2 to the method area.
4) Class analysis. Omit (the process of replacing the symbol references in the constant pool with direct references)
5) Initialization of the class. Perform the assignment of static properties. First order private static Singleton singleton = new Singleton ( ), according to conclusions 1 and conclusions 2 does not perform the assignment of this operation layer, value1 and value2. Therefore, value1 and value2 in the singleton object are only ++ operations on the basis of 0. At this time, value1=1 and value2=1 in the singleton object.
Then, public static int value1 = 5; public static int value2 = 3; These two lines of code actually perform the assignment operation. So the final result: 5 and 3.
If the implementation is public static int value1; public static int value2; what will be the result? Result: 1 and 1.

Note: Why does Singleton singleton = new Singleton() not assign value1, value2? Because the assignment of static variables is only done once in the initialization of the class.
When the program executes private static Singleton singleton = new Singleton(), it is already assigning values ​​to the static variables of the Singleton class. Here new Singleton() is a special assignment, similar to the recursive inner layer, the outer layer is already an assignment operation, so the inner layer will automatically filter the assignment operation of static variables. But non-static variables will still be assigned.

Conclusion 3: On the basis of conclusion 2, non-static resources will be initialized with the creation of the object. Every time an object is created, an initialization is performed.

Mastering conclusions 1, 2, and 3 are basically familiar with the order of program execution in java classes. This is not enough, ClassLoader has not been introduced yet.

Class loader

JVM provides the following three system class loaders:

  • Bootstrap ClassLoader : The top-level class loader is responsible for loading the JAVA_HOME\lib directory or in the path specified by the -Xbootclasspath parameter, and is recognized by the virtual machine (identified by the file name, such as rt.jar )the type.
  • Extension ClassLoader : Responsible for loading the class library in the JAVA_HOME\lib\ext directory or in the path specified by the java.ext.dirs system variable.
  • Application ClassLoader : Also called the system class loader, it can be obtained through getSystemClassLoader(), and is responsible for loading the class library on the user path (classpath). If there is no custom class loader, this is generally the default class loader.

Object creation:

img

Disclaimer: This blog post is a study note and refers to some network resources. If there is any infringement, please let us know by private message!

Guess you like

Origin blog.csdn.net/qq_42380734/article/details/105397532