Class loader to parent delegation model (11)

Class loader

The Java virtual machine design team intends to implement the action of "getting a binary byte stream describing the class through the fully qualified name of a class" in the class loading stage outside the Java virtual machine so that the application can decide how to do so Get the required class, and the code that implements this action is called "" Class Loader "".

For any class, the uniqueness of the class and the class loader in the Java virtual machine must be established together, and each class loader has an independent namespace.
Popular expression : comparing whether two classes are " equal ", it only makes sense when the two classes are loaded by the same class loader, even if they are from the same Class file and loaded by the same virtual machine, as long as they are loaded The class loaders are different, so the two classes must not be equal.
The equality referred to here includes the equals() method, isAssignableFrom() method, and the return result of the isInstance() method of the Class object representing the class.

Parental Delegation Model

From the perspective of the Java virtual machine, there are only two different class loaders: self-starting class loaders, which are implemented by C++, are part of the virtual machine itself , and all other class loaders . These class loaders are all implemented by the Java language, exist independently outside the virtual machine, and all inherit from the abstract class java.lang.ClassLoader.

For JDK8 and previous versions, most Java programs will be loaded using the class loaders provided by the following three systems.

  1. Bootstrap Class Loader (Bootstrap Class Loader): This class loader is used to load and store in the <Java_Home>\lib directory or in the path specified by the -Xbootclasspath parameter, and is loaded into the class library recognized by the Java virtual machine In the memory of the Java virtual machine.
  2. Extension Class Loader: This class loader is implemented in the form of Java code in the class sun.misc.Launcher$ExtClassLoader. It is responsible for loading all class libraries in the <Java_Home>\lib\ext directory or in the path specified by the java.ext.dirs system variable.
  3. Application class loader: Since the application class loader is the return value of the getSystem-ClassLoader() method in the ClassLoader class, it is called "system class loader" in some occasions, and it is responsible for loading all on the user path (ClassPath) Class library. If the application does not define its own class loader, it is generally used as the default loader.

Before JDK9, these three types of loaders cooperated to complete the loading.

Parent delegation model :
Parental Delegation Model
Except for the top-level startup class loader, all other classes should have their own parent class loader. However, the parent-child relationship here is not achieved through inheritance, but usually uses a composition relationship to reuse the code of the parent loader.

The working process of the parent delegation model : If a class loader receives a class loading request, it will not try to load the class by itself at first, but will delegate the request to its parent loader to complete, each level of class loader This is the case until the top-level initialization loader, only when the parent loader reports that it cannot complete the loading of this class, the child loader will try to load.

The advantages of using the parent delegation model : Java classes along with its class loader have a hierarchical relationship with priority. No matter which class loader loads a class, it will first be delegated to the top class loader to load, because the Object class is guaranteed to be the same class in various class loader environments of the program.

Implementation of the Parental Delegation Model

protected synchronized Class<> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
    
    
// 检查类是否已经被加载过
	Class c = findLoadedClass(name);
	if (c == null)
	{
    
    
		try
		{
    
    
			if (parent != null)
			{
    
    	
				c = parent.loadClass(name,false);
			}
			else
			{
    
    
			// 父类加载器为空,则直接调用启动类加载器作为父类加载器
				c = findBootstrapClassOrNull(name);
			}
		}
		catch(ClassNotFoundException e)
		{
    
    
			// 如果父类抛出此异常,说明父类无法加载此请求。
		}
		if (c == null)
		{
    
    
		// 父类无法加载时,调用自身的findClass方法进行类加载
			c = findClass(name);
		}
	}
	if (resolve)
	{
    
    
		resolveClass(c);
	}
	return c;
}

Guess you like

Origin blog.csdn.net/weixin_43663421/article/details/109310675