Detailed introduction to the basic Java class loading process
Basic process:
- Load the binary byte stream that defines the class based on the fully qualified name of the class.
- Convert the static storage structure represented by the byte stream into the runtime data structure of the method area
- Generate a java.lang.Class object representing this class in memory, and use it as a method to access various data access portals of this class.
The array class itself is not created through the class loader, but is created directly by the Java virtual machine, and the element type of the array class is loaded by the class loader.
Element type of array class: the type of array after removing all dimensions.
File format verification:
- 0xCAFEBABY starts with magic number;
- The current virtual machine can handle the primary and secondary version number;
- constant type;
- Index execution type;
- utf8 encoded data type,
Metadata verification: Semantic analysis of bytecode description information:
- Whether there is a parent class;
- Whether the parent class inherits the final modified class;
- Whether a non-extracted class implements the methods that need to be implemented in the parent class or interface;
- Overwrite of fields and methods in the class, overload contradictions;
Bytecode verification: Determine the legality and correctness of the program through semantic flow and control flow analysis, and method body analysis verification.
- Symbol reference verification: When the virtual machine converts symbol reference into direct reference, in the parsing stage, it performs matching verification on information outside the class itself.
- Whether the corresponding class can be found by fully qualified names described by characters in symbolic references;
- Specifies whether there are descriptors in the class that match the method field, as well as methods and fields described by the simple name;
- Accessibility of classes, fields, and methods in symbolic references.
Preparation: Allocate memory for class variables in the method area and set the initial value of class variables.
- The initial value is usually the zero value of the data type, and the final modified value is directly initialized to the corresponding value.
- Class variables are statically modified variables, distinguished from instance variables.
Analysis: The virtual machine replaces symbolic references in the constant pool with direct reference process
CONSTANT_Class_info,CONSTANT_Fieldref_info,CONSTANT_Methodref_info..
- Symbol reference: Use a set of symbols to describe the referenced target. Any form of literals can be positioned unambiguously when used. It has nothing to do with the virtual machine memory implementation and whether the reference target is loaded.
- Direct reference: A pointer directly to the target, an offset or a handle that is indirectly located to the target, is related to the memory implemented by the virtual machine. The direct reference related target object must be loaded.
- . . .
Initialization: Start executing Java program code in the class definition. Execute the class constructor <cinit>() method,
<cinit>():
- The compiler automatically collects the assignment actions of class variables in the class according to the definition order in the class file and merges the statements of the static statement block. The static statement block can only access the variables defined before.
- Different from the class constructor, the parent class constructor is not required to be called as shown. The virtual machine ensures that the parent class <cinit>() has been executed before the subclass is executed.
- The static statement block in the parent class is executed first.
- <cinit>() is not necessary for classes or interfaces, and will not be generated if there is no variable assignment operation or static statement block.
- The <cinit>() of the interface does not need to execute the <cinit>() of the parent interface first, and the same interface implementation class <cinit>() is not required.
- Thread safety: The virtual machine ensures that <cinit>() is correctly locked and synchronized in a multi-threaded environment. Only one thread can access the <cinit>() of the initialization class at the same time.
Thank you for reading, I hope it can help you. Thank you for your support for this site!