Classification and relationship of class loaders

Classification and relationship of class loaders

  • The JVM supports two types of class loaders. They are Bootstrap ClassLoader and User-Defined
    ClassLoader.
  • Conceptually, a custom class loader generally refers to a class loader customized by the developer in the program, but the Java virtual machine specification does not define it as such, but loads all classes derived from the abstract class ClassLoader All are divided into custom class loaders.

No matter how the types of class loaders are divided, there are always only three of our most common class loaders in the program, as shown in the following figure:

Note: After JDK1.9, the extended class loader ExtClassLoader becomes the PlatFromClassLoader platform loader.
Insert picture description here
The four here are the containment relationship, not the upper and lower layers, nor the inheritance relationship of subsystems.

We pass a class to get its different loaders:

public class ClassLoaderTest {
    
    
    public static void main(String[] args) {
    
    
        //获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        //获取其上层的:扩展类加载器
        ClassLoader classLoaderParent = systemClassLoader.getParent();
        System.out.println(classLoaderParent);
        
        //获取根加载器
        ClassLoader loaderParentParent = classLoaderParent.getParent();
        System.out.println(loaderParentParent);
        
        //获取自定义加载器
        ClassLoader loader = ClassLoaderTest.class.getClassLoader();
        System.out.println(loader);
        
        //获取String类型的加载器
        ClassLoader classLoader = String.class.getClassLoader();
        System.out.println(classLoader);
    }
}

It can be seen from the results that the root loader cannot be obtained directly from the code, and the loader currently used by the user code is the system class loader. At the same time, we obtain the loader of the String type and find it is null, which means that the String type is loaded through the root loader, which means that Java's core class libraries are loaded using the root loader.

jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
jdk.internal.loader.ClassLoaders$PlatformClassLoader@58ceff1
null
jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
null

Note: The PlatformClassLoader here can be regarded as ExtClassLoader.

Loader that comes with the virtual machine

Start the class loader (bootstrap class loader, Bootstrap ClassLoader)

  • This class loader is implemented in C/C++ language and is nested inside the JVM.
  • It is used to load the core Java libraries (the contents under the path of JAVAHOME/jre/1ib/rt.jar, resources.jar, or sun.boot.class.path) to provide the classes needed by the JVM itself.
  • It does not inherit from java.lang.ClassLoader and has no parent loader.
  • Load the extension class loader and application class loader, and designate them as their parent class loader.
  • For security reasons, Bootstrap startup class loader only loads classes whose package names start with java, javax, sun, etc.

Extension ClassLoader

  • Written in Java language, JDK1.8 is implemented by sun.misc.Launcher$ExtClassLoader, and changed to PlatFromClassLoader after JDK1.9, which is implemented by jdk.internal.loader.PlatformClassLoader.
  • Derived from the ClassLoader class.
  • The parent class loader is the startup class loader.
  • Load the class library from the directory specified by the java.ext.dirs system property, or load the class library from the jre/lib/ext subdirectory (extension directory) of the JDK installation directory. If the JAR created by the user is placed in this directory, it will also be automatically loaded by the extension class loader.

Application class loader (system class loader, AppClassLoader)

  • Written in java language and implemented by sun.misc.LaunchersAppClassLoader.
  • Derived from the ClassLoader class.
  • The parent class loader is the extended class loader.
  • It is responsible for loading the class library under the path specified by the environment variable classpath or the system property java.class.path.
  • This class loading is the default class loader in the program. Generally speaking, Java application classes are loaded by it
    . The class loader can be obtained through the classLoader#getSystemclassLoader() method.

User-defined class loader

In the daily application development of Java, the loading of classes is almost performed by the above three types of loaders. When necessary, we can also customize the class loaders to customize the way the classes are loaded. Why do you want to customize the class loader?

  • Load class in isolation
  • Modify the way the class is loaded
  • Extension loading source
  • Prevent source code leakage

Implementation steps of user-defined class loader:

  • Developers can implement their own class loader by inheriting the abstract class Java.lang.ClassLoader to meet some special needs.
  • Before JDK1.2, when customizing the class loader, you always inherited the ClassLoader class and rewritten the loadClass() method to achieve a custom class loading class, but after JDK1.2, it is no longer recommended for users to override 1oadclass() method, but it is recommended to write custom class loading logic in the findclass() method.
  • When writing a custom class loader, if there are no too complex requirements, you can directly inherit the URIClassLoader class, so that you can avoid writing your own findclass() method and the way to get the bytecode stream, and make the custom class loader The writing is more concise.

ClassLoader class

ClassLoader class, it is an abstract class, all subsequent class loaders inherit from ClassLoader (not including the startup class loader).

Ways to obtain ClassLoader:

  • Get the current ClassLoader: clazz.getClassLoader()
  • Get the ClassLoader of the current thread context: Thread.currentThread().getContextClassLoader()
  • Get the ClassLoader of the system: ClassLoader.getSystemClassLoader()
  • Get the caller's ClassLoader: DriverManager.getCallerClassLoader()

Guess you like

Origin blog.csdn.net/qq_33626996/article/details/112847648