In the last article, we looked at the loading mechanism of Java classes in detail. In this article, we will continue to look at Java class loaders.

The contents of this study:

What is a class loader? Tree hierarchy of Class loaders How class loaders work Parent delegate model The process of class loading

The Class loader is used to load Java classes into the Java virtual machine. In general, virtual machines with Java classes use Java as follows: Java source programs (.java files) are converted to Java bytecode (.class files) after being compiled by the Java compiler. The classloader is responsible for reading the Java bytecode and converting it into an instance of the java.lang.Class Class. Each such instance is used to represent a Java class. An object of this class is created using the newInstance() method of this instance. The actual situation may be more complex, as Java bytecode may be dynamically generated by a tool or downloaded over a network.

The tree hierarchy of class loaders

Classloaders in Java can be roughly divided into two classes, one provided by the system and the other written by Java application developers.

Tree hierarchy diagram of class loaders

1. Bootstrap class loader:

It is used to load the Java core library (jre/lib/rt.jar), which is implemented using native C++ code and does not inherit from java.lang.classloader. Loading extension classes and application classloaders, and specifying their parent classloaders, is not available in Java.

2. Extensions Class Loader:

It is used to load Java extension libraries (jre/ext/*.jar). The Implementation of the Java Virtual machine provides an extension library directory. The class loader finds and loads Java classes in this directory.

3. System Class Loader:

It loads Java classes based on the Java application’s CLASSPATH. In general, Java application classes are loaded by it. Through this. GetSystemClassLoader () to get it.

4. Custom class loader:

In addition to the system-provided classloaders, developers can implement their own classloaders by inheriting java.lang.ClassLoader classes to meet special needs.

Test code examples:

Output result:

The test case shows that the ClassLoader class is loaded by AppClassLoader. His father is an ExtClassLoader, and ExtClassLoader’s father can’t get it because it’s implemented in C++.

Third, the working mechanism of class loader

The virtual machine loads the data describing the Class from the Class file to the memory, verifies, transforms, and initializes the data, and finally forms Java types that can be directly used by virtual machines. This is the Class loading mechanism of virtual machines.

A class loader is an object component that finds the bytecode file of a class and constructs the representation of the class within the JVM. In Java, the classloader loads a class into the JVM by following these steps:

1. Load: find and import Class files;

2. Linking: Perform verification, preparation, and parsing steps, where parsing steps are optional;

(1) Verification: check the correctness of the loaded Class file data;

(2) Preparation: allocate storage space for tired static variables;

(3) Parsing: convert symbolic reference into direct reference;

3. Initialization: Perform initialization of static variables and static code blocks of the class.

Class loading is handled by ClassLoader and its subclasses. ClassLoader is an important Java runtime system component that finds and loads Class bytecode files at runtime. The JVM generates three classloaders at runtime: the root loader, the extension ClassLoader, and the application ClassLoader. The root loader is not a subclass of ClassLoader; it is written in C++, so we do not see it in Java. The root loader is responsible for loading the core JRE libraries, such as large Rt. jar and charsets.jar under the JRE target. Extension classloaders and application classloaders are subclasses of ClassLoader. The extension ClassLoader is responsible for loading the JAR class package in the JRE extension directory Ext. The application class loader is responsible for loading the class package in the Classpath path.

4. Parental delegation model

Parent delegates model procedures

When a specific class loader receives a request to load a class, it first delegates the loading task to the parent class loader, recursively. If the parent class loader can complete the class loading task, it returns successfully. Only if the parent class loader is unable to complete the load task, do the load itself.

The advantage of using the parent delegate model is that Java classes have a hierarchy of priorities along with their classloaders. For example, the java.lang.Object class, which resides in rt.jar, is delegated to the Bootstrap ClassLoader at the top of the model by any ClassLoader. Therefore, the Object class is the same class in each ClassLoader environment of the program. On the other hand, if there were no parent delegate model and each class loader loaded it by itself, if the user wrote a java.lang.Object class of the same name and put it in the ClassPath, the system would have multiple Object classes and the program would be confused. So, if a developer tries to write a Java class with the same name as one in the Rt.jar library, it will compile fine, but it will never be loaded and run.

System implementation of parental delegation model

In the java.lang.classloader loadClass() method, first check whether it has been loaded. If not, the parent loadClass() method is called. If the parent is empty, the startup ClassLoader is used as the parent by default. If the parent load fails, throw a ClassNotFoundException and then call your own findClass() method to load.

Class loader process

First let’s take a look at the class loader process diagram, as follows:

Java class loader process diagram

The classloader process consists of three major steps:

loading

1. Loading means reading the class file into memory and creating a java.lang.class object for it.

2. Get the binary byte stream of the class by its fully qualified name.

3. Convert the static storage structure represented by this byte stream to the runtime data structure of the method area.

4. Generate a Class object in memory as an access point to the various data of the Class in the method area.

Loading is usually done by the class loader. There are several specific ways to load classes:

1. Load local resources.

2. Load the network. Web applets.

3. Load the zip package. The jar, war.

4. Run time compute generation. Dynamic proxy technology.

5. Other files are generated. The JSP application.

6. Read from an encrypted file, mainly to prevent class files from being decompiled.

link

Linking is divided into three steps:

1. Verify

Ensure that the byte stream of the class file contains information that meets the requirements of the virtual machine.

Mainly including, file format verification, metadata verification, bytecode verification, symbol reference verification.

2. Prepare

Allocates memory for class variables and assigns a value of zero to the variables.

Static with final is not included here, because final is allocated when mutated, and the preparation phase is explicitly initialized. Initialization is not assigned to instance variables.

3. The parsing

Turns symbolic references in the constant pool into direct references.

Initialize the

The initialization phase is to execute the class constructor method () method.

The () method is automatically generated by javac combining the class variable assignment action with statements in a static code block. This method is not automatically generated when a class does not have class variables and static code blocks. A class is loaded only once, and the () method is locked synchronously.

Sum up so much, have you learned?