preface

The five phases of load, validate, prepare, initialize, and unload are in a definite order, and the loading of a class must be intermixed in this order, not necessarily the parsing phase, which in some cases may begin after the initialization phase because Java supports runtime binding.

The body of the

The flow chart

Load (Load)

Find and import class files

The principle of

  1. Get the binary byte stream that defines a class by its fully qualified name.
  2. Transform the static storage structure represented by this byte stream into the runtime data structure of the method area.
  3. A Java.lang. Class object representing this Class is generated in the Java heap as an access point to the data in the method area.
Loading a. Class file
  1. Load from the local system
  2. Download and load from the network: for example, applets?
  3. Load from jar, WAR
  4. Load from a proprietary database
  5. Dynamically compile Java source files into.class files and load them: dynamic proxies, for example
  6. Load it from an encrypted file

The storage space

  1. Method area: class information, static variables, constants.
  2. Heap: the java.lang.Class object of the loaded Class.

Connection (Link)

The load phase is not complete. The connect phase has started. They're going to cross over.

Validation (Verify)

To ensure that the byte stream in the Class file contains exactly the information required by the current virtual machine, and that our code does not compromise the security of the virtual machine itself and cause the virtual machine to crash.

  1. File format validation
  2. Metadata validation
  3. Bytecode verification
  4. Symbolic reference verification

Prepare for

Allocate memory for a class variable (static variable) and set its default initial value; Static variables modified by final are not included, since memory is allocated at compile time and initialization is displayed during preparation; Memory is also not allocated by instance variables (member variables that are not static), which are stored in the method area, whereas instance variables are stored in the Java heap.

Resolve (Resolve)

Convert a symbolic reference to a class to a direct reference

Initialize

The initialization phase is the process of executing the class constructor () method. In simple terms, the preparation phase assigns initial values to class variables, in this case values defined by the programmer, as well as other resources

Two ways to initialize a class variable
  1. Declare the specified initial value of a class variable directly
  2. Use static code blocks to specify initial values for class variables

Initialization steps

  1. If the class has not already been loaded and connected, the program loads and connects the class first
  2. If the class’s immediate parent has not already been initialized, its immediate parent is initialized first
  3. If there are initializers in a class, the system executes those initializers in turn

use

Note: Only active use of a class causes initialization of the class.

Take the initiative to use

  1. new
  2. Access a static variable of a class/interface, or perform an assignment to that static variable
  3. Call a static method of a class
  4. reflection
  5. If you initialize a subclass of a class, its parent class is initialized as well
  6. Run a class directly, main()

Passive use

  1. Using a static field of a parent class only causes initialization of the parent class, not of the child class.
  2. Defining an array of classes does not cause the class to be initialized.Object[] o = new Object[6];
  3. Referring to a class’s static final constant does not cause the class to be initialized (it would still cause the class to be initialized if there were only static modifiers).

uninstall

Clear the class information in the method area

After a class is used, it is unloaded if:

  1. All instances of the class have been reclaimed, meaning that there are no instances of the class in the Java heap.
  2. The ClassLoader that loaded the class has been reclaimed.
  3. The java.lang.Class object corresponding to this Class is not referenced anywhere, and the methods of this Class cannot be accessed through reflection anywhere.

Class loading mechanism

  1. Full responsibility: When a class loader loads a class object, its dependent, referenced class objects are also loaded by that class loader, unless the display is loaded using another class loader.
  2. Parent class delegate: When a class loader loads a class object, it first hands it to the parent class loader for loading. Only when the parent class loader cannot retrieve the corresponding bytecode file, it searches for it in its own classpath and loads it.
  3. Caching mechanism: all loaded class objects are cached in memory. When the class loader needs to use it, it will find the corresponding class object in memory. If not, it will find the corresponding binary data, convert it into a class object, and store it in the cache.
How to break the parent delegate mechanism
  1. SPI: For example, java.sql.Driver is an interface defined in rt.jar. It is loaded by bootstrap classLoader according to parental delegation rules, but the Driver can be implemented by the user. So it is loaded by the ThreadContextClassLoader, the System ClassLoader.
  2. Implement classLoader yourself: inherit the abstract classLoader class and rewrite the loadClass method. The display uses its own class loader to load the specified class and needs to move the class out of the current directory to prevent it from being found and loaded by the previous class loader.